From 1e5d512c216d329effa693b91ef64652945def6a Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 11 Mar 2003 13:05:43 +0000 Subject: [PATCH] Moved sources from src/org/** to src/java/org/** git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196061 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/AWTStarter.java | 152 ++ .../apache/fop/apps/CommandLineOptions.java | 725 +++++++ .../apache/fop/apps/CommandLineStarter.java | 122 ++ src/java/org/apache/fop/apps/Driver.java | 748 +++++++ .../org/apache/fop/apps/FOInputHandler.java | 104 + .../org/apache/fop/apps/FOPException.java | 150 ++ src/java/org/apache/fop/apps/Fop.java | 91 + .../org/apache/fop/apps/InputHandler.java | 133 ++ .../org/apache/fop/apps/LayoutHandler.java | 312 +++ .../org/apache/fop/apps/PrintStarter.java | 239 ++ src/java/org/apache/fop/apps/Starter.java | 107 + .../org/apache/fop/apps/StructureHandler.java | 295 +++ .../org/apache/fop/apps/TraxInputHandler.java | 152 ++ src/java/org/apache/fop/apps/Version.java | 67 + .../org/apache/fop/apps/XSLTInputHandler.java | 182 ++ src/java/org/apache/fop/apps/package.html | 7 + src/java/org/apache/fop/area/Area.java | 265 +++ src/java/org/apache/fop/area/AreaTree.java | 248 +++ .../org/apache/fop/area/AreaTreeModel.java | 114 + src/java/org/apache/fop/area/BeforeFloat.java | 97 + src/java/org/apache/fop/area/Block.java | 135 ++ src/java/org/apache/fop/area/BlockParent.java | 188 ++ .../org/apache/fop/area/BlockViewport.java | 110 + src/java/org/apache/fop/area/BodyRegion.java | 173 ++ src/java/org/apache/fop/area/CTM.java | 282 +++ .../fop/area/CachedRenderPagesModel.java | 157 ++ src/java/org/apache/fop/area/Flow.java | 63 + src/java/org/apache/fop/area/Footnote.java | 88 + src/java/org/apache/fop/area/LineArea.java | 147 ++ src/java/org/apache/fop/area/LineTrait.java | 60 + .../org/apache/fop/area/MainReference.java | 101 + src/java/org/apache/fop/area/Page.java | 166 ++ .../org/apache/fop/area/PageViewport.java | 407 ++++ .../org/apache/fop/area/RegionReference.java | 164 ++ .../org/apache/fop/area/RegionViewport.java | 147 ++ .../org/apache/fop/area/RenderPagesModel.java | 223 ++ src/java/org/apache/fop/area/Resolveable.java | 87 + src/java/org/apache/fop/area/Span.java | 112 + .../org/apache/fop/area/StorePagesModel.java | 179 ++ src/java/org/apache/fop/area/Title.java | 60 + src/java/org/apache/fop/area/Trait.java | 475 ++++ src/java/org/apache/fop/area/TreeExt.java | 103 + .../org/apache/fop/area/inline/Anchor.java | 63 + .../org/apache/fop/area/inline/Character.java | 89 + .../org/apache/fop/area/inline/Container.java | 109 + .../apache/fop/area/inline/FilledArea.java | 100 + .../apache/fop/area/inline/ForeignObject.java | 96 + .../org/apache/fop/area/inline/Image.java | 82 + .../apache/fop/area/inline/InlineArea.java | 205 ++ .../apache/fop/area/inline/InlineParent.java | 111 + .../org/apache/fop/area/inline/Leader.java | 121 ++ .../org/apache/fop/area/inline/Space.java | 69 + .../fop/area/inline/UnresolvedPageNumber.java | 115 + .../org/apache/fop/area/inline/Viewport.java | 164 ++ src/java/org/apache/fop/area/inline/Word.java | 118 + .../org/apache/fop/datatypes/AutoLength.java | 77 + .../org/apache/fop/datatypes/ColorType.java | 741 +++++++ .../fop/datatypes/CompoundDatatype.java | 74 + .../org/apache/fop/datatypes/CondLength.java | 123 ++ .../org/apache/fop/datatypes/FODimension.java | 68 + .../org/apache/fop/datatypes/FixedLength.java | 118 + src/java/org/apache/fop/datatypes/Keep.java | 123 ++ .../org/apache/fop/datatypes/KeepValue.java | 81 + src/java/org/apache/fop/datatypes/Length.java | 148 ++ .../org/apache/fop/datatypes/LengthBase.java | 136 ++ .../org/apache/fop/datatypes/LengthPair.java | 95 + .../org/apache/fop/datatypes/LengthRange.java | 211 ++ .../datatypes/LinearCombinationLength.java | 84 + .../org/apache/fop/datatypes/MixedLength.java | 134 ++ .../org/apache/fop/datatypes/PercentBase.java | 57 + .../apache/fop/datatypes/PercentLength.java | 107 + src/java/org/apache/fop/datatypes/Space.java | 104 + .../apache/fop/datatypes/TableColLength.java | 111 + .../apache/fop/datatypes/ToBeImplemented.java | 62 + .../datatypes/ToBeImplementedProperty.java | 87 + .../org/apache/fop/datatypes/package.html | 6 + .../apache/fop/extensions/BookmarkData.java | 271 +++ .../org/apache/fop/extensions/Bookmarks.java | 118 + .../extensions/ExtensionElementMapping.java | 111 + .../apache/fop/extensions/ExtensionObj.java | 71 + src/java/org/apache/fop/extensions/Label.java | 92 + .../org/apache/fop/extensions/Outline.java | 144 ++ .../apache/fop/fo/AbstractCharIterator.java | 102 + .../apache/fop/fo/BoxPropShorthandParser.java | 88 + src/java/org/apache/fop/fo/CharIterator.java | 62 + .../org/apache/fop/fo/CharacterProperty.java | 87 + src/java/org/apache/fop/fo/ColorProfile.java | 120 + .../org/apache/fop/fo/ColorTypeProperty.java | 93 + .../org/apache/fop/fo/CondLengthProperty.java | 85 + src/java/org/apache/fop/fo/Declarations.java | 107 + .../org/apache/fop/fo/ElementMapping.java | 67 + src/java/org/apache/fop/fo/EnumProperty.java | 104 + .../org/apache/fop/fo/FOElementMapping.java | 486 +++++ src/java/org/apache/fop/fo/FONode.java | 203 ++ src/java/org/apache/fop/fo/FOText.java | 180 ++ src/java/org/apache/fop/fo/FOTreeBuilder.java | 275 +++ src/java/org/apache/fop/fo/FOUserAgent.java | 220 ++ src/java/org/apache/fop/fo/FObj.java | 376 ++++ src/java/org/apache/fop/fo/FObjMixed.java | 113 + .../apache/fop/fo/GenericShorthandParser.java | 107 + .../org/apache/fop/fo/InlineCharIterator.java | 106 + src/java/org/apache/fop/fo/KeepProperty.java | 79 + .../org/apache/fop/fo/LengthPairProperty.java | 79 + .../org/apache/fop/fo/LengthProperty.java | 130 ++ .../apache/fop/fo/LengthRangeProperty.java | 79 + src/java/org/apache/fop/fo/ListProperty.java | 93 + .../org/apache/fop/fo/NumberProperty.java | 119 + .../org/apache/fop/fo/OneCharIterator.java | 79 + src/java/org/apache/fop/fo/Property.java | 490 +++++ src/java/org/apache/fop/fo/PropertyList.java | 416 ++++ .../apache/fop/fo/PropertyListBuilder.java | 305 +++ .../org/apache/fop/fo/PropertyManager.java | 582 +++++ .../apache/fop/fo/RecursiveCharIterator.java | 134 ++ .../org/apache/fop/fo/ShorthandParser.java | 57 + src/java/org/apache/fop/fo/SpaceProperty.java | 84 + .../org/apache/fop/fo/StringProperty.java | 107 + src/java/org/apache/fop/fo/TextInfo.java | 82 + src/java/org/apache/fop/fo/Title.java | 131 ++ .../apache/fop/fo/ToBeImplementedElement.java | 67 + src/java/org/apache/fop/fo/Unknown.java | 74 + src/java/org/apache/fop/fo/UnknownXMLObj.java | 98 + src/java/org/apache/fop/fo/XMLElement.java | 88 + src/java/org/apache/fop/fo/XMLObj.java | 195 ++ .../org/apache/fop/fo/expr/AbsFunction.java | 72 + .../apache/fop/fo/expr/BodyStartFunction.java | 82 + .../apache/fop/fo/expr/CeilingFunction.java | 72 + .../org/apache/fop/fo/expr/FloorFunction.java | 73 + .../fop/fo/expr/FopPropValFunction.java | 75 + .../fop/fo/expr/FromParentFunction.java | 79 + .../fop/fo/expr/FromTableColumnFunction.java | 71 + src/java/org/apache/fop/fo/expr/Function.java | 62 + .../org/apache/fop/fo/expr/FunctionBase.java | 70 + .../fop/fo/expr/InheritedPropFunction.java | 71 + .../apache/fop/fo/expr/LabelEndFunction.java | 100 + .../org/apache/fop/fo/expr/MaxFunction.java | 73 + .../org/apache/fop/fo/expr/MinFunction.java | 73 + .../apache/fop/fo/expr/NCnameProperty.java | 80 + .../fop/fo/expr/NearestSpecPropFunction.java | 73 + src/java/org/apache/fop/fo/expr/Numeric.java | 420 ++++ .../apache/fop/fo/expr/NumericProperty.java | 85 + .../fop/fo/expr/PPColWidthFunction.java | 78 + .../apache/fop/fo/expr/PropertyException.java | 58 + .../org/apache/fop/fo/expr/PropertyInfo.java | 138 ++ .../apache/fop/fo/expr/PropertyParser.java | 499 +++++ .../apache/fop/fo/expr/PropertyTokenizer.java | 394 ++++ .../apache/fop/fo/expr/RGBColorFunction.java | 110 + .../org/apache/fop/fo/expr/RoundFunction.java | 77 + .../org/apache/fop/fo/flow/BasicLink.java | 216 ++ .../org/apache/fop/fo/flow/BidiOverride.java | 154 ++ src/java/org/apache/fop/fo/flow/Block.java | 385 ++++ .../apache/fop/fo/flow/BlockContainer.java | 154 ++ .../org/apache/fop/fo/flow/Character.java | 170 ++ .../apache/fop/fo/flow/ExternalGraphic.java | 321 +++ src/java/org/apache/fop/fo/flow/Float.java | 76 + src/java/org/apache/fop/fo/flow/Flow.java | 163 ++ src/java/org/apache/fop/fo/flow/Footnote.java | 89 + .../org/apache/fop/fo/flow/FootnoteBody.java | 70 + .../fop/fo/flow/InitialPropertySet.java | 101 + src/java/org/apache/fop/fo/flow/Inline.java | 147 ++ .../apache/fop/fo/flow/InlineContainer.java | 145 ++ .../fop/fo/flow/InstreamForeignObject.java | 387 ++++ src/java/org/apache/fop/fo/flow/Leader.java | 308 +++ .../org/apache/fop/fo/flow/ListBlock.java | 148 ++ src/java/org/apache/fop/fo/flow/ListItem.java | 157 ++ .../org/apache/fop/fo/flow/ListItemBody.java | 94 + .../org/apache/fop/fo/flow/ListItemLabel.java | 94 + src/java/org/apache/fop/fo/flow/Marker.java | 111 + .../org/apache/fop/fo/flow/MultiCase.java | 78 + .../apache/fop/fo/flow/MultiProperties.java | 75 + .../apache/fop/fo/flow/MultiPropertySet.java | 72 + .../org/apache/fop/fo/flow/MultiSwitch.java | 76 + .../org/apache/fop/fo/flow/MultiToggle.java | 76 + .../org/apache/fop/fo/flow/PageNumber.java | 185 ++ .../fop/fo/flow/PageNumberCitation.java | 246 +++ .../apache/fop/fo/flow/RetrieveMarker.java | 109 + .../org/apache/fop/fo/flow/StaticContent.java | 90 + src/java/org/apache/fop/fo/flow/Table.java | 208 ++ .../apache/fop/fo/flow/TableAndCaption.java | 107 + .../org/apache/fop/fo/flow/TableBody.java | 125 ++ .../org/apache/fop/fo/flow/TableCaption.java | 100 + .../org/apache/fop/fo/flow/TableCell.java | 358 +++ .../org/apache/fop/fo/flow/TableColumn.java | 151 ++ .../org/apache/fop/fo/flow/TableFooter.java | 62 + .../org/apache/fop/fo/flow/TableHeader.java | 62 + src/java/org/apache/fop/fo/flow/TableRow.java | 157 ++ src/java/org/apache/fop/fo/flow/Wrapper.java | 76 + .../ConditionalPageMasterReference.java | 200 ++ .../fop/fo/pagination/LayoutMasterSet.java | 222 ++ .../fo/pagination/PageMasterReference.java | 120 + .../fo/pagination/PageNumberGenerator.java | 208 ++ .../fop/fo/pagination/PageSequence.java | 807 +++++++ .../fop/fo/pagination/PageSequenceMaster.java | 200 ++ .../org/apache/fop/fo/pagination/Region.java | 289 +++ .../apache/fop/fo/pagination/RegionAfter.java | 112 + .../apache/fop/fo/pagination/RegionBA.java | 120 + .../apache/fop/fo/pagination/RegionBASE.java | 86 + .../fop/fo/pagination/RegionBefore.java | 117 + .../apache/fop/fo/pagination/RegionBody.java | 173 ++ .../apache/fop/fo/pagination/RegionEnd.java | 113 + .../apache/fop/fo/pagination/RegionSE.java | 102 + .../apache/fop/fo/pagination/RegionStart.java | 112 + .../RepeatablePageMasterAlternatives.java | 168 ++ .../RepeatablePageMasterReference.java | 129 ++ .../org/apache/fop/fo/pagination/Root.java | 141 ++ .../fop/fo/pagination/SimplePageMaster.java | 273 +++ .../pagination/SinglePageMasterReference.java | 97 + .../fo/pagination/SubSequenceSpecifier.java | 81 + src/java/org/apache/fop/fonts/BFEntry.java | 98 + src/java/org/apache/fop/fonts/CIDFont.java | 107 + .../org/apache/fop/fonts/CIDFontType.java | 110 + src/java/org/apache/fop/fonts/CustomFont.java | 370 ++++ src/java/org/apache/fop/fonts/Font.java | 83 + .../org/apache/fop/fonts/FontDescriptor.java | 116 + .../org/apache/fop/fonts/FontMetrics.java | 138 ++ src/java/org/apache/fop/fonts/FontType.java | 141 ++ src/java/org/apache/fop/fonts/Glyphs.java | 1331 ++++++++++++ src/java/org/apache/fop/fonts/LazyFont.java | 287 +++ .../org/apache/fop/fonts/MultiByteFont.java | 359 +++ .../org/apache/fop/fonts/MutableFont.java | 158 ++ .../org/apache/fop/fonts/SingleByteFont.java | 128 ++ .../org/apache/fop/fonts/apps/PFMReader.java | 421 ++++ .../org/apache/fop/fonts/apps/TTFReader.java | 544 +++++ .../org/apache/fop/fonts/base14/package.html | 6 + src/java/org/apache/fop/fonts/package.html | 6 + .../fop/fonts/truetype/FontFileReader.java | 367 ++++ .../fop/fonts/truetype/TTFCmapEntry.java | 138 ++ .../fop/fonts/truetype/TTFDirTabEntry.java | 125 ++ .../apache/fop/fonts/truetype/TTFFile.java | 1327 ++++++++++++ .../fop/fonts/truetype/TTFMtxEntry.java | 226 ++ .../fop/fonts/truetype/TTFSubSetFile.java | 886 ++++++++ .../apache/fop/fonts/truetype/package.html | 6 + .../org/apache/fop/fonts/type1/PFBData.java | 192 ++ .../org/apache/fop/fonts/type1/PFBParser.java | 276 +++ .../org/apache/fop/fonts/type1/PFMFile.java | 468 ++++ .../fop/fonts/type1/PFMInputStream.java | 139 ++ .../org/apache/fop/fonts/type1/package.html | 6 + .../apache/fop/image/AbstractFopImage.java | 332 +++ src/java/org/apache/fop/image/BmpImage.java | 255 +++ src/java/org/apache/fop/image/EPSImage.java | 153 ++ src/java/org/apache/fop/image/FopImage.java | 196 ++ .../apache/fop/image/FopImageConsumer.java | 243 +++ src/java/org/apache/fop/image/GifImage.java | 241 +++ src/java/org/apache/fop/image/ImageCache.java | 96 + .../org/apache/fop/image/ImageFactory.java | 541 +++++ .../org/apache/fop/image/ImageLoader.java | 94 + src/java/org/apache/fop/image/JAIImage.java | 183 ++ src/java/org/apache/fop/image/JimiImage.java | 216 ++ src/java/org/apache/fop/image/JpegImage.java | 235 ++ src/java/org/apache/fop/image/XMLImage.java | 108 + .../apache/fop/image/analyser/BMPReader.java | 136 ++ .../apache/fop/image/analyser/EPSReader.java | 280 +++ .../apache/fop/image/analyser/GIFReader.java | 132 ++ .../fop/image/analyser/ImageReader.java | 87 + .../image/analyser/ImageReaderFactory.java | 123 ++ .../apache/fop/image/analyser/JPEGReader.java | 195 ++ .../apache/fop/image/analyser/PNGReader.java | 144 ++ .../apache/fop/image/analyser/SVGReader.java | 261 +++ .../apache/fop/image/analyser/TIFFReader.java | 162 ++ .../apache/fop/image/analyser/XMLReader.java | 182 ++ .../fop/layout/AbsolutePositionProps.java | 67 + .../apache/fop/layout/AccessibilityProps.java | 64 + src/java/org/apache/fop/layout/AreaClass.java | 82 + .../org/apache/fop/layout/AuralProps.java | 78 + .../apache/fop/layout/BackgroundProps.java | 69 + .../apache/fop/layout/BorderAndPadding.java | 210 ++ src/java/org/apache/fop/layout/FontInfo.java | 270 +++ src/java/org/apache/fop/layout/FontState.java | 206 ++ .../apache/fop/layout/HyphenationProps.java | 66 + .../apache/fop/layout/MarginInlineProps.java | 66 + .../org/apache/fop/layout/MarginProps.java | 68 + .../org/apache/fop/layout/PageMaster.java | 68 + .../fop/layout/RelativePositionProps.java | 68 + src/java/org/apache/fop/layout/TextState.java | 107 + .../fop/layout/hyphenation/ByteVector.java | 158 ++ .../fop/layout/hyphenation/CharVector.java | 168 ++ .../apache/fop/layout/hyphenation/Hyphen.java | 102 + .../fop/layout/hyphenation/Hyphenation.java | 117 + .../hyphenation/HyphenationException.java | 66 + .../layout/hyphenation/HyphenationTree.java | 569 +++++ .../fop/layout/hyphenation/Hyphenator.java | 312 +++ .../layout/hyphenation/PatternConsumer.java | 89 + .../fop/layout/hyphenation/PatternParser.java | 465 ++++ .../fop/layout/hyphenation/TernaryTree.java | 701 ++++++ .../fop/layoutmgr/AbstractLayoutManager.java | 397 ++++ .../BlockContainerLayoutManager.java | 343 +++ .../fop/layoutmgr/BlockLayoutManager.java | 349 +++ .../layoutmgr/BlockStackingLayoutManager.java | 165 ++ .../org/apache/fop/layoutmgr/BreakCost.java | 90 + .../org/apache/fop/layoutmgr/BreakPoss.java | 293 +++ .../fop/layoutmgr/BreakPossPosIter.java | 107 + .../fop/layoutmgr/ContentLayoutManager.java | 277 +++ .../fop/layoutmgr/FlowLayoutManager.java | 207 ++ .../org/apache/fop/layoutmgr/HyphContext.java | 91 + .../InlineStackingLayoutManager.java | 618 ++++++ src/java/org/apache/fop/layoutmgr/LMiter.java | 139 ++ .../apache/fop/layoutmgr/LayoutContext.java | 258 +++ .../apache/fop/layoutmgr/LayoutManager.java | 85 + .../apache/fop/layoutmgr/LayoutProcessor.java | 232 ++ .../fop/layoutmgr/LeafNodeLayoutManager.java | 287 +++ .../apache/fop/layoutmgr/LeafPosition.java | 66 + .../fop/layoutmgr/LineLayoutManager.java | 673 ++++++ .../org/apache/fop/layoutmgr/MinOptMax.java | 161 ++ .../apache/fop/layoutmgr/NonLeafPosition.java | 66 + .../fop/layoutmgr/PageLayoutManager.java | 689 ++++++ .../org/apache/fop/layoutmgr/Position.java | 73 + .../fop/layoutmgr/PositionIterator.java | 133 ++ .../RetrieveMarkerLayoutManager.java | 175 ++ .../apache/fop/layoutmgr/SpaceSpecifier.java | 184 ++ .../layoutmgr/StaticContentLayoutManager.java | 166 ++ .../fop/layoutmgr/TextLayoutManager.java | 587 +++++ .../org/apache/fop/layoutmgr/TraitSetter.java | 187 ++ .../org/apache/fop/layoutmgr/list/Item.java | 286 +++ .../list/ListBlockLayoutManager.java | 275 +++ .../layoutmgr/list/ListItemLayoutManager.java | 339 +++ .../org/apache/fop/layoutmgr/table/Body.java | 306 +++ .../apache/fop/layoutmgr/table/Caption.java | 241 +++ .../org/apache/fop/layoutmgr/table/Cell.java | 308 +++ .../apache/fop/layoutmgr/table/Column.java | 159 ++ .../org/apache/fop/layoutmgr/table/Row.java | 417 ++++ .../table/TableAndCaptionLayoutManager.java | 242 +++ .../layoutmgr/table/TableLayoutManager.java | 398 ++++ src/java/org/apache/fop/mif/MIFElement.java | 149 ++ src/java/org/apache/fop/mif/MIFFile.java | 169 ++ src/java/org/apache/fop/mif/MIFHandler.java | 251 +++ src/java/org/apache/fop/mif/PGFElement.java | 80 + src/java/org/apache/fop/mif/RefElement.java | 75 + .../org/apache/fop/mif/RulingElement.java | 82 + .../org/apache/fop/pdf/ASCII85Filter.java | 242 +++ .../org/apache/fop/pdf/ASCIIHexFilter.java | 106 + src/java/org/apache/fop/pdf/BitmapImage.java | 239 ++ src/java/org/apache/fop/pdf/DCTFilter.java | 100 + src/java/org/apache/fop/pdf/FlateFilter.java | 271 +++ .../apache/fop/pdf/InMemoryStreamCache.java | 160 ++ src/java/org/apache/fop/pdf/PDFAction.java | 98 + src/java/org/apache/fop/pdf/PDFAnnotList.java | 128 ++ src/java/org/apache/fop/pdf/PDFArray.java | 93 + src/java/org/apache/fop/pdf/PDFCIDFont.java | 291 +++ .../apache/fop/pdf/PDFCIDFontDescriptor.java | 119 + .../org/apache/fop/pdf/PDFCIDSystemInfo.java | 111 + src/java/org/apache/fop/pdf/PDFCMap.java | 515 +++++ src/java/org/apache/fop/pdf/PDFCharProcs.java | 98 + src/java/org/apache/fop/pdf/PDFColor.java | 481 ++++ .../org/apache/fop/pdf/PDFColorSpace.java | 198 ++ src/java/org/apache/fop/pdf/PDFDocument.java | 1926 +++++++++++++++++ src/java/org/apache/fop/pdf/PDFEncoding.java | 167 ++ src/java/org/apache/fop/pdf/PDFFileSpec.java | 124 ++ src/java/org/apache/fop/pdf/PDFFilter.java | 130 ++ .../apache/fop/pdf/PDFFilterException.java | 75 + src/java/org/apache/fop/pdf/PDFFont.java | 264 +++ .../org/apache/fop/pdf/PDFFontDescriptor.java | 227 ++ .../org/apache/fop/pdf/PDFFontNonBase14.java | 140 ++ .../org/apache/fop/pdf/PDFFontTrueType.java | 79 + src/java/org/apache/fop/pdf/PDFFontType0.java | 142 ++ src/java/org/apache/fop/pdf/PDFFontType1.java | 83 + src/java/org/apache/fop/pdf/PDFFontType3.java | 177 ++ .../org/apache/fop/pdf/PDFFormXObject.java | 126 ++ src/java/org/apache/fop/pdf/PDFFunction.java | 845 ++++++++ src/java/org/apache/fop/pdf/PDFGState.java | 245 +++ src/java/org/apache/fop/pdf/PDFGoTo.java | 196 ++ .../org/apache/fop/pdf/PDFGoToRemote.java | 184 ++ src/java/org/apache/fop/pdf/PDFICCStream.java | 115 + src/java/org/apache/fop/pdf/PDFImage.java | 159 ++ src/java/org/apache/fop/pdf/PDFInfo.java | 174 ++ .../org/apache/fop/pdf/PDFInternalLink.java | 88 + src/java/org/apache/fop/pdf/PDFLink.java | 163 ++ src/java/org/apache/fop/pdf/PDFNumber.java | 147 ++ src/java/org/apache/fop/pdf/PDFObject.java | 128 ++ src/java/org/apache/fop/pdf/PDFOutline.java | 224 ++ src/java/org/apache/fop/pdf/PDFPage.java | 201 ++ src/java/org/apache/fop/pdf/PDFPages.java | 136 ++ src/java/org/apache/fop/pdf/PDFPathPaint.java | 109 + src/java/org/apache/fop/pdf/PDFPattern.java | 453 ++++ src/java/org/apache/fop/pdf/PDFRectangle.java | 126 ++ .../apache/fop/pdf/PDFResourceContext.java | 156 ++ src/java/org/apache/fop/pdf/PDFResources.java | 232 ++ src/java/org/apache/fop/pdf/PDFRoot.java | 183 ++ src/java/org/apache/fop/pdf/PDFShading.java | 670 ++++++ src/java/org/apache/fop/pdf/PDFState.java | 385 ++++ src/java/org/apache/fop/pdf/PDFStream.java | 388 ++++ src/java/org/apache/fop/pdf/PDFT1Stream.java | 129 ++ src/java/org/apache/fop/pdf/PDFTTFStream.java | 111 + src/java/org/apache/fop/pdf/PDFUri.java | 88 + src/java/org/apache/fop/pdf/PDFWArray.java | 173 ++ src/java/org/apache/fop/pdf/PDFXObject.java | 213 ++ src/java/org/apache/fop/pdf/StreamCache.java | 149 ++ .../apache/fop/pdf/TempFileStreamCache.java | 198 ++ .../apache/fop/pdf/TransitionDictionary.java | 99 + src/java/org/apache/fop/pdf/package.html | 8 + .../apache/fop/render/AbstractRenderer.java | 654 ++++++ .../org/apache/fop/render/PrintRenderer.java | 89 + src/java/org/apache/fop/render/Renderer.java | 255 +++ .../apache/fop/render/RendererContext.java | 127 ++ .../org/apache/fop/render/XMLHandler.java | 77 + .../apache/fop/render/awt/AWTFontMetrics.java | 315 +++ .../apache/fop/render/awt/AWTRenderer.java | 197 ++ .../fop/render/awt/FontMetricsMapper.java | 198 ++ .../org/apache/fop/render/awt/FontSetup.java | 213 ++ src/java/org/apache/fop/render/package.html | 6 + .../apache/fop/render/pcl/PCLRenderer.java | 217 ++ .../org/apache/fop/render/pcl/PCLStream.java | 89 + .../org/apache/fop/render/pdf/CTMHelper.java | 145 ++ .../apache/fop/render/pdf/EmbedFontInfo.java | 112 + .../org/apache/fop/render/pdf/FontReader.java | 321 +++ .../org/apache/fop/render/pdf/FontSetup.java | 270 +++ .../apache/fop/render/pdf/FontTriplet.java | 96 + .../apache/fop/render/pdf/FopPDFImage.java | 307 +++ .../apache/fop/render/pdf/PDFRenderer.java | 1361 ++++++++++++ .../apache/fop/render/pdf/PDFXMLHandler.java | 338 +++ .../org/apache/fop/render/pdf/package.html | 6 + .../fop/render/ps/ASCII85OutputStream.java | 254 +++ .../fop/render/ps/ASCIIHexOutputStream.java | 134 ++ .../apache/fop/render/ps/DSCConstants.java | 202 ++ .../org/apache/fop/render/ps/Finalizable.java | 74 + .../render/ps/FlateEncodeOutputStream.java | 85 + .../org/apache/fop/render/ps/PSGenerator.java | 371 ++++ .../apache/fop/render/ps/PSGraphics2D.java | 1134 ++++++++++ .../org/apache/fop/render/ps/PSProcSets.java | 200 ++ .../org/apache/fop/render/ps/PSRenderer.java | 901 ++++++++ .../org/apache/fop/render/ps/PSState.java | 97 + .../fop/render/ps/PSTextElementBridge.java | 159 ++ .../apache/fop/render/ps/PSTextPainter.java | 435 ++++ .../apache/fop/render/ps/PSXMLHandler.java | 379 ++++ .../ps/RunLengthEncodeOutputStream.java | 217 ++ .../apache/fop/render/svg/SVGRenderer.java | 457 ++++ .../apache/fop/render/txt/TXTRenderer.java | 172 ++ .../org/apache/fop/render/txt/TXTStream.java | 98 + .../apache/fop/render/xml/XMLRenderer.java | 536 +++++ .../apache/fop/render/xml/XMLXMLHandler.java | 213 ++ .../org/apache/fop/render/xml/package.html | 6 + .../apache/fop/rtf/renderer/RTFHandler.java | 204 ++ .../apache/fop/servlet/FopPrintServlet.java | 317 +++ .../org/apache/fop/servlet/FopServlet.java | 255 +++ src/java/org/apache/fop/servlet/package.html | 6 + .../org/apache/fop/svg/PDFAElementBridge.java | 124 ++ src/java/org/apache/fop/svg/PDFANode.java | 156 ++ .../apache/fop/svg/PDFDocumentGraphics2D.java | 279 +++ .../org/apache/fop/svg/PDFGraphics2D.java | 1660 ++++++++++++++ .../fop/svg/PDFGraphicsConfiguration.javat | 178 ++ .../org/apache/fop/svg/PDFGraphicsDevice.java | 127 ++ .../apache/fop/svg/PDFImageElementBridge.java | 181 ++ .../apache/fop/svg/PDFTextElementBridge.java | 154 ++ .../org/apache/fop/svg/PDFTextPainter.java | 434 ++++ .../org/apache/fop/svg/PDFTranscoder.java | 439 ++++ src/java/org/apache/fop/svg/SVGElement.java | 314 +++ .../org/apache/fop/svg/SVGElementMapping.java | 115 + src/java/org/apache/fop/svg/SVGObj.java | 79 + src/java/org/apache/fop/svg/SVGUserAgent.java | 184 ++ src/java/org/apache/fop/svg/SVGUtilities.java | 301 +++ src/java/org/apache/fop/svg/package.html | 31 + .../org/apache/fop/tools/AreaTreeBuilder.java | 782 +++++++ .../apache/fop/tools/DocumentInputSource.java | 99 + .../org/apache/fop/tools/DocumentReader.java | 551 +++++ .../org/apache/fop/tools/TestConverter.java | 391 ++++ .../apache/fop/tools/anttasks/Compare.java | 235 ++ .../org/apache/fop/tools/anttasks/Fop.java | 503 +++++ .../apache/fop/tools/anttasks/RunTest.java | 256 +++ .../tools/anttasks/SerializeHyphPattern.java | 197 ++ .../apache/fop/tools/xslt/TraxTransform.java | 194 ++ .../apache/fop/tools/xslt/XSLTransform.java | 215 ++ .../org/apache/fop/traits/BlockProps.java | 65 + .../org/apache/fop/traits/BorderProps.java | 84 + .../org/apache/fop/traits/InlineProps.java | 66 + .../org/apache/fop/traits/LayoutProps.java | 103 + src/java/org/apache/fop/traits/SpaceVal.java | 137 ++ .../org/apache/fop/util/CharUtilities.java | 232 ++ .../org/apache/fop/util/StreamUtilities.java | 243 +++ src/java/org/apache/fop/viewer/Command.java | 114 + .../org/apache/fop/viewer/GoToPageDialog.java | 160 ++ .../org/apache/fop/viewer/PreviewDialog.java | 587 +++++ .../fop/viewer/PreviewDialogAboutBox.java | 150 ++ .../org/apache/fop/viewer/Translator.java | 91 + .../org/apache/fop/viewer/images/Print.gif | Bin 0 -> 992 bytes .../org/apache/fop/viewer/images/firstpg.gif | Bin 0 -> 885 bytes src/java/org/apache/fop/viewer/images/fop.gif | Bin 0 -> 2452 bytes .../org/apache/fop/viewer/images/lastpg.gif | Bin 0 -> 889 bytes .../org/apache/fop/viewer/images/nextpg.gif | Bin 0 -> 869 bytes .../org/apache/fop/viewer/images/prevpg.gif | Bin 0 -> 867 bytes .../org/apache/fop/viewer/images/reload.gif | Bin 0 -> 889 bytes .../fop/viewer/resources/Viewer.properties | 44 + .../fop/viewer/resources/Viewer_cs.properties | 34 + .../fop/viewer/resources/Viewer_de.properties | 32 + .../fop/viewer/resources/Viewer_fi.properties | 23 + .../fop/viewer/resources/Viewer_fr.properties | 21 + .../fop/viewer/resources/Viewer_it.properties | 21 + .../fop/viewer/resources/Viewer_ja.properties | 28 + .../fop/viewer/resources/Viewer_pl.properties | 24 + .../fop/viewer/resources/Viewer_ru.properties | 43 + .../fop/viewer/resources/Viewer_tr.properties | 33 + 488 files changed, 97103 insertions(+) create mode 100644 src/java/org/apache/fop/apps/AWTStarter.java create mode 100644 src/java/org/apache/fop/apps/CommandLineOptions.java create mode 100644 src/java/org/apache/fop/apps/CommandLineStarter.java create mode 100644 src/java/org/apache/fop/apps/Driver.java create mode 100644 src/java/org/apache/fop/apps/FOInputHandler.java create mode 100644 src/java/org/apache/fop/apps/FOPException.java create mode 100644 src/java/org/apache/fop/apps/Fop.java create mode 100644 src/java/org/apache/fop/apps/InputHandler.java create mode 100644 src/java/org/apache/fop/apps/LayoutHandler.java create mode 100644 src/java/org/apache/fop/apps/PrintStarter.java create mode 100644 src/java/org/apache/fop/apps/Starter.java create mode 100644 src/java/org/apache/fop/apps/StructureHandler.java create mode 100644 src/java/org/apache/fop/apps/TraxInputHandler.java create mode 100644 src/java/org/apache/fop/apps/Version.java create mode 100644 src/java/org/apache/fop/apps/XSLTInputHandler.java create mode 100644 src/java/org/apache/fop/apps/package.html create mode 100644 src/java/org/apache/fop/area/Area.java create mode 100644 src/java/org/apache/fop/area/AreaTree.java create mode 100644 src/java/org/apache/fop/area/AreaTreeModel.java create mode 100644 src/java/org/apache/fop/area/BeforeFloat.java create mode 100644 src/java/org/apache/fop/area/Block.java create mode 100644 src/java/org/apache/fop/area/BlockParent.java create mode 100644 src/java/org/apache/fop/area/BlockViewport.java create mode 100644 src/java/org/apache/fop/area/BodyRegion.java create mode 100644 src/java/org/apache/fop/area/CTM.java create mode 100644 src/java/org/apache/fop/area/CachedRenderPagesModel.java create mode 100644 src/java/org/apache/fop/area/Flow.java create mode 100644 src/java/org/apache/fop/area/Footnote.java create mode 100644 src/java/org/apache/fop/area/LineArea.java create mode 100644 src/java/org/apache/fop/area/LineTrait.java create mode 100644 src/java/org/apache/fop/area/MainReference.java create mode 100644 src/java/org/apache/fop/area/Page.java create mode 100644 src/java/org/apache/fop/area/PageViewport.java create mode 100644 src/java/org/apache/fop/area/RegionReference.java create mode 100644 src/java/org/apache/fop/area/RegionViewport.java create mode 100644 src/java/org/apache/fop/area/RenderPagesModel.java create mode 100644 src/java/org/apache/fop/area/Resolveable.java create mode 100644 src/java/org/apache/fop/area/Span.java create mode 100644 src/java/org/apache/fop/area/StorePagesModel.java create mode 100644 src/java/org/apache/fop/area/Title.java create mode 100644 src/java/org/apache/fop/area/Trait.java create mode 100644 src/java/org/apache/fop/area/TreeExt.java create mode 100644 src/java/org/apache/fop/area/inline/Anchor.java create mode 100644 src/java/org/apache/fop/area/inline/Character.java create mode 100644 src/java/org/apache/fop/area/inline/Container.java create mode 100644 src/java/org/apache/fop/area/inline/FilledArea.java create mode 100644 src/java/org/apache/fop/area/inline/ForeignObject.java create mode 100644 src/java/org/apache/fop/area/inline/Image.java create mode 100644 src/java/org/apache/fop/area/inline/InlineArea.java create mode 100644 src/java/org/apache/fop/area/inline/InlineParent.java create mode 100644 src/java/org/apache/fop/area/inline/Leader.java create mode 100644 src/java/org/apache/fop/area/inline/Space.java create mode 100644 src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java create mode 100644 src/java/org/apache/fop/area/inline/Viewport.java create mode 100644 src/java/org/apache/fop/area/inline/Word.java create mode 100644 src/java/org/apache/fop/datatypes/AutoLength.java create mode 100644 src/java/org/apache/fop/datatypes/ColorType.java create mode 100644 src/java/org/apache/fop/datatypes/CompoundDatatype.java create mode 100644 src/java/org/apache/fop/datatypes/CondLength.java create mode 100644 src/java/org/apache/fop/datatypes/FODimension.java create mode 100644 src/java/org/apache/fop/datatypes/FixedLength.java create mode 100644 src/java/org/apache/fop/datatypes/Keep.java create mode 100644 src/java/org/apache/fop/datatypes/KeepValue.java create mode 100644 src/java/org/apache/fop/datatypes/Length.java create mode 100644 src/java/org/apache/fop/datatypes/LengthBase.java create mode 100644 src/java/org/apache/fop/datatypes/LengthPair.java create mode 100644 src/java/org/apache/fop/datatypes/LengthRange.java create mode 100644 src/java/org/apache/fop/datatypes/LinearCombinationLength.java create mode 100644 src/java/org/apache/fop/datatypes/MixedLength.java create mode 100644 src/java/org/apache/fop/datatypes/PercentBase.java create mode 100644 src/java/org/apache/fop/datatypes/PercentLength.java create mode 100644 src/java/org/apache/fop/datatypes/Space.java create mode 100644 src/java/org/apache/fop/datatypes/TableColLength.java create mode 100644 src/java/org/apache/fop/datatypes/ToBeImplemented.java create mode 100644 src/java/org/apache/fop/datatypes/ToBeImplementedProperty.java create mode 100644 src/java/org/apache/fop/datatypes/package.html create mode 100644 src/java/org/apache/fop/extensions/BookmarkData.java create mode 100644 src/java/org/apache/fop/extensions/Bookmarks.java create mode 100644 src/java/org/apache/fop/extensions/ExtensionElementMapping.java create mode 100644 src/java/org/apache/fop/extensions/ExtensionObj.java create mode 100644 src/java/org/apache/fop/extensions/Label.java create mode 100644 src/java/org/apache/fop/extensions/Outline.java create mode 100644 src/java/org/apache/fop/fo/AbstractCharIterator.java create mode 100644 src/java/org/apache/fop/fo/BoxPropShorthandParser.java create mode 100644 src/java/org/apache/fop/fo/CharIterator.java create mode 100644 src/java/org/apache/fop/fo/CharacterProperty.java create mode 100644 src/java/org/apache/fop/fo/ColorProfile.java create mode 100644 src/java/org/apache/fop/fo/ColorTypeProperty.java create mode 100644 src/java/org/apache/fop/fo/CondLengthProperty.java create mode 100644 src/java/org/apache/fop/fo/Declarations.java create mode 100644 src/java/org/apache/fop/fo/ElementMapping.java create mode 100644 src/java/org/apache/fop/fo/EnumProperty.java create mode 100644 src/java/org/apache/fop/fo/FOElementMapping.java create mode 100644 src/java/org/apache/fop/fo/FONode.java create mode 100644 src/java/org/apache/fop/fo/FOText.java create mode 100644 src/java/org/apache/fop/fo/FOTreeBuilder.java create mode 100644 src/java/org/apache/fop/fo/FOUserAgent.java create mode 100644 src/java/org/apache/fop/fo/FObj.java create mode 100644 src/java/org/apache/fop/fo/FObjMixed.java create mode 100644 src/java/org/apache/fop/fo/GenericShorthandParser.java create mode 100644 src/java/org/apache/fop/fo/InlineCharIterator.java create mode 100644 src/java/org/apache/fop/fo/KeepProperty.java create mode 100644 src/java/org/apache/fop/fo/LengthPairProperty.java create mode 100644 src/java/org/apache/fop/fo/LengthProperty.java create mode 100644 src/java/org/apache/fop/fo/LengthRangeProperty.java create mode 100644 src/java/org/apache/fop/fo/ListProperty.java create mode 100644 src/java/org/apache/fop/fo/NumberProperty.java create mode 100644 src/java/org/apache/fop/fo/OneCharIterator.java create mode 100644 src/java/org/apache/fop/fo/Property.java create mode 100644 src/java/org/apache/fop/fo/PropertyList.java create mode 100644 src/java/org/apache/fop/fo/PropertyListBuilder.java create mode 100644 src/java/org/apache/fop/fo/PropertyManager.java create mode 100644 src/java/org/apache/fop/fo/RecursiveCharIterator.java create mode 100644 src/java/org/apache/fop/fo/ShorthandParser.java create mode 100644 src/java/org/apache/fop/fo/SpaceProperty.java create mode 100644 src/java/org/apache/fop/fo/StringProperty.java create mode 100644 src/java/org/apache/fop/fo/TextInfo.java create mode 100644 src/java/org/apache/fop/fo/Title.java create mode 100644 src/java/org/apache/fop/fo/ToBeImplementedElement.java create mode 100644 src/java/org/apache/fop/fo/Unknown.java create mode 100644 src/java/org/apache/fop/fo/UnknownXMLObj.java create mode 100644 src/java/org/apache/fop/fo/XMLElement.java create mode 100644 src/java/org/apache/fop/fo/XMLObj.java create mode 100644 src/java/org/apache/fop/fo/expr/AbsFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/BodyStartFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/CeilingFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/FloorFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/FopPropValFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/FromParentFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/Function.java create mode 100644 src/java/org/apache/fop/fo/expr/FunctionBase.java create mode 100644 src/java/org/apache/fop/fo/expr/InheritedPropFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/LabelEndFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/MaxFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/MinFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/NCnameProperty.java create mode 100644 src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/Numeric.java create mode 100644 src/java/org/apache/fop/fo/expr/NumericProperty.java create mode 100644 src/java/org/apache/fop/fo/expr/PPColWidthFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/PropertyException.java create mode 100644 src/java/org/apache/fop/fo/expr/PropertyInfo.java create mode 100644 src/java/org/apache/fop/fo/expr/PropertyParser.java create mode 100644 src/java/org/apache/fop/fo/expr/PropertyTokenizer.java create mode 100644 src/java/org/apache/fop/fo/expr/RGBColorFunction.java create mode 100644 src/java/org/apache/fop/fo/expr/RoundFunction.java create mode 100644 src/java/org/apache/fop/fo/flow/BasicLink.java create mode 100644 src/java/org/apache/fop/fo/flow/BidiOverride.java create mode 100644 src/java/org/apache/fop/fo/flow/Block.java create mode 100644 src/java/org/apache/fop/fo/flow/BlockContainer.java create mode 100644 src/java/org/apache/fop/fo/flow/Character.java create mode 100644 src/java/org/apache/fop/fo/flow/ExternalGraphic.java create mode 100644 src/java/org/apache/fop/fo/flow/Float.java create mode 100644 src/java/org/apache/fop/fo/flow/Flow.java create mode 100644 src/java/org/apache/fop/fo/flow/Footnote.java create mode 100644 src/java/org/apache/fop/fo/flow/FootnoteBody.java create mode 100644 src/java/org/apache/fop/fo/flow/InitialPropertySet.java create mode 100644 src/java/org/apache/fop/fo/flow/Inline.java create mode 100644 src/java/org/apache/fop/fo/flow/InlineContainer.java create mode 100644 src/java/org/apache/fop/fo/flow/InstreamForeignObject.java create mode 100644 src/java/org/apache/fop/fo/flow/Leader.java create mode 100644 src/java/org/apache/fop/fo/flow/ListBlock.java create mode 100644 src/java/org/apache/fop/fo/flow/ListItem.java create mode 100644 src/java/org/apache/fop/fo/flow/ListItemBody.java create mode 100644 src/java/org/apache/fop/fo/flow/ListItemLabel.java create mode 100644 src/java/org/apache/fop/fo/flow/Marker.java create mode 100644 src/java/org/apache/fop/fo/flow/MultiCase.java create mode 100644 src/java/org/apache/fop/fo/flow/MultiProperties.java create mode 100644 src/java/org/apache/fop/fo/flow/MultiPropertySet.java create mode 100644 src/java/org/apache/fop/fo/flow/MultiSwitch.java create mode 100644 src/java/org/apache/fop/fo/flow/MultiToggle.java create mode 100644 src/java/org/apache/fop/fo/flow/PageNumber.java create mode 100644 src/java/org/apache/fop/fo/flow/PageNumberCitation.java create mode 100644 src/java/org/apache/fop/fo/flow/RetrieveMarker.java create mode 100644 src/java/org/apache/fop/fo/flow/StaticContent.java create mode 100644 src/java/org/apache/fop/fo/flow/Table.java create mode 100644 src/java/org/apache/fop/fo/flow/TableAndCaption.java create mode 100644 src/java/org/apache/fop/fo/flow/TableBody.java create mode 100644 src/java/org/apache/fop/fo/flow/TableCaption.java create mode 100644 src/java/org/apache/fop/fo/flow/TableCell.java create mode 100644 src/java/org/apache/fop/fo/flow/TableColumn.java create mode 100644 src/java/org/apache/fop/fo/flow/TableFooter.java create mode 100644 src/java/org/apache/fop/fo/flow/TableHeader.java create mode 100644 src/java/org/apache/fop/fo/flow/TableRow.java create mode 100644 src/java/org/apache/fop/fo/flow/Wrapper.java create mode 100644 src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java create mode 100644 src/java/org/apache/fop/fo/pagination/LayoutMasterSet.java create mode 100644 src/java/org/apache/fop/fo/pagination/PageMasterReference.java create mode 100644 src/java/org/apache/fop/fo/pagination/PageNumberGenerator.java create mode 100644 src/java/org/apache/fop/fo/pagination/PageSequence.java create mode 100644 src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java create mode 100644 src/java/org/apache/fop/fo/pagination/Region.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionAfter.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionBA.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionBASE.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionBefore.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionBody.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionEnd.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionSE.java create mode 100644 src/java/org/apache/fop/fo/pagination/RegionStart.java create mode 100644 src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java create mode 100644 src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java create mode 100644 src/java/org/apache/fop/fo/pagination/Root.java create mode 100644 src/java/org/apache/fop/fo/pagination/SimplePageMaster.java create mode 100644 src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java create mode 100644 src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java create mode 100644 src/java/org/apache/fop/fonts/BFEntry.java create mode 100644 src/java/org/apache/fop/fonts/CIDFont.java create mode 100644 src/java/org/apache/fop/fonts/CIDFontType.java create mode 100644 src/java/org/apache/fop/fonts/CustomFont.java create mode 100644 src/java/org/apache/fop/fonts/Font.java create mode 100644 src/java/org/apache/fop/fonts/FontDescriptor.java create mode 100644 src/java/org/apache/fop/fonts/FontMetrics.java create mode 100644 src/java/org/apache/fop/fonts/FontType.java create mode 100644 src/java/org/apache/fop/fonts/Glyphs.java create mode 100644 src/java/org/apache/fop/fonts/LazyFont.java create mode 100644 src/java/org/apache/fop/fonts/MultiByteFont.java create mode 100644 src/java/org/apache/fop/fonts/MutableFont.java create mode 100644 src/java/org/apache/fop/fonts/SingleByteFont.java create mode 100644 src/java/org/apache/fop/fonts/apps/PFMReader.java create mode 100644 src/java/org/apache/fop/fonts/apps/TTFReader.java create mode 100644 src/java/org/apache/fop/fonts/base14/package.html create mode 100644 src/java/org/apache/fop/fonts/package.html create mode 100644 src/java/org/apache/fop/fonts/truetype/FontFileReader.java create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFFile.java create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java create mode 100644 src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java create mode 100644 src/java/org/apache/fop/fonts/truetype/package.html create mode 100644 src/java/org/apache/fop/fonts/type1/PFBData.java create mode 100644 src/java/org/apache/fop/fonts/type1/PFBParser.java create mode 100644 src/java/org/apache/fop/fonts/type1/PFMFile.java create mode 100644 src/java/org/apache/fop/fonts/type1/PFMInputStream.java create mode 100644 src/java/org/apache/fop/fonts/type1/package.html create mode 100644 src/java/org/apache/fop/image/AbstractFopImage.java create mode 100644 src/java/org/apache/fop/image/BmpImage.java create mode 100644 src/java/org/apache/fop/image/EPSImage.java create mode 100644 src/java/org/apache/fop/image/FopImage.java create mode 100644 src/java/org/apache/fop/image/FopImageConsumer.java create mode 100644 src/java/org/apache/fop/image/GifImage.java create mode 100644 src/java/org/apache/fop/image/ImageCache.java create mode 100644 src/java/org/apache/fop/image/ImageFactory.java create mode 100644 src/java/org/apache/fop/image/ImageLoader.java create mode 100644 src/java/org/apache/fop/image/JAIImage.java create mode 100644 src/java/org/apache/fop/image/JimiImage.java create mode 100644 src/java/org/apache/fop/image/JpegImage.java create mode 100644 src/java/org/apache/fop/image/XMLImage.java create mode 100644 src/java/org/apache/fop/image/analyser/BMPReader.java create mode 100644 src/java/org/apache/fop/image/analyser/EPSReader.java create mode 100644 src/java/org/apache/fop/image/analyser/GIFReader.java create mode 100644 src/java/org/apache/fop/image/analyser/ImageReader.java create mode 100644 src/java/org/apache/fop/image/analyser/ImageReaderFactory.java create mode 100644 src/java/org/apache/fop/image/analyser/JPEGReader.java create mode 100644 src/java/org/apache/fop/image/analyser/PNGReader.java create mode 100644 src/java/org/apache/fop/image/analyser/SVGReader.java create mode 100644 src/java/org/apache/fop/image/analyser/TIFFReader.java create mode 100644 src/java/org/apache/fop/image/analyser/XMLReader.java create mode 100644 src/java/org/apache/fop/layout/AbsolutePositionProps.java create mode 100644 src/java/org/apache/fop/layout/AccessibilityProps.java create mode 100644 src/java/org/apache/fop/layout/AreaClass.java create mode 100644 src/java/org/apache/fop/layout/AuralProps.java create mode 100644 src/java/org/apache/fop/layout/BackgroundProps.java create mode 100644 src/java/org/apache/fop/layout/BorderAndPadding.java create mode 100644 src/java/org/apache/fop/layout/FontInfo.java create mode 100644 src/java/org/apache/fop/layout/FontState.java create mode 100644 src/java/org/apache/fop/layout/HyphenationProps.java create mode 100644 src/java/org/apache/fop/layout/MarginInlineProps.java create mode 100644 src/java/org/apache/fop/layout/MarginProps.java create mode 100644 src/java/org/apache/fop/layout/PageMaster.java create mode 100644 src/java/org/apache/fop/layout/RelativePositionProps.java create mode 100644 src/java/org/apache/fop/layout/TextState.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/ByteVector.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/CharVector.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/Hyphen.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/Hyphenation.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/HyphenationException.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/HyphenationTree.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/Hyphenator.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/PatternConsumer.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/PatternParser.java create mode 100644 src/java/org/apache/fop/layout/hyphenation/TernaryTree.java create mode 100644 src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/BreakCost.java create mode 100644 src/java/org/apache/fop/layoutmgr/BreakPoss.java create mode 100644 src/java/org/apache/fop/layoutmgr/BreakPossPosIter.java create mode 100644 src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/HyphContext.java create mode 100644 src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/LMiter.java create mode 100644 src/java/org/apache/fop/layoutmgr/LayoutContext.java create mode 100644 src/java/org/apache/fop/layoutmgr/LayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/LayoutProcessor.java create mode 100644 src/java/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/LeafPosition.java create mode 100644 src/java/org/apache/fop/layoutmgr/LineLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/MinOptMax.java create mode 100644 src/java/org/apache/fop/layoutmgr/NonLeafPosition.java create mode 100644 src/java/org/apache/fop/layoutmgr/PageLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/Position.java create mode 100644 src/java/org/apache/fop/layoutmgr/PositionIterator.java create mode 100644 src/java/org/apache/fop/layoutmgr/RetrieveMarkerLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java create mode 100644 src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/TextLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/TraitSetter.java create mode 100644 src/java/org/apache/fop/layoutmgr/list/Item.java create mode 100644 src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/Body.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/Caption.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/Cell.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/Column.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/Row.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java create mode 100644 src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java create mode 100644 src/java/org/apache/fop/mif/MIFElement.java create mode 100644 src/java/org/apache/fop/mif/MIFFile.java create mode 100644 src/java/org/apache/fop/mif/MIFHandler.java create mode 100644 src/java/org/apache/fop/mif/PGFElement.java create mode 100644 src/java/org/apache/fop/mif/RefElement.java create mode 100644 src/java/org/apache/fop/mif/RulingElement.java create mode 100644 src/java/org/apache/fop/pdf/ASCII85Filter.java create mode 100644 src/java/org/apache/fop/pdf/ASCIIHexFilter.java create mode 100644 src/java/org/apache/fop/pdf/BitmapImage.java create mode 100644 src/java/org/apache/fop/pdf/DCTFilter.java create mode 100644 src/java/org/apache/fop/pdf/FlateFilter.java create mode 100644 src/java/org/apache/fop/pdf/InMemoryStreamCache.java create mode 100644 src/java/org/apache/fop/pdf/PDFAction.java create mode 100644 src/java/org/apache/fop/pdf/PDFAnnotList.java create mode 100644 src/java/org/apache/fop/pdf/PDFArray.java create mode 100644 src/java/org/apache/fop/pdf/PDFCIDFont.java create mode 100644 src/java/org/apache/fop/pdf/PDFCIDFontDescriptor.java create mode 100644 src/java/org/apache/fop/pdf/PDFCIDSystemInfo.java create mode 100644 src/java/org/apache/fop/pdf/PDFCMap.java create mode 100644 src/java/org/apache/fop/pdf/PDFCharProcs.java create mode 100644 src/java/org/apache/fop/pdf/PDFColor.java create mode 100644 src/java/org/apache/fop/pdf/PDFColorSpace.java create mode 100644 src/java/org/apache/fop/pdf/PDFDocument.java create mode 100644 src/java/org/apache/fop/pdf/PDFEncoding.java create mode 100644 src/java/org/apache/fop/pdf/PDFFileSpec.java create mode 100644 src/java/org/apache/fop/pdf/PDFFilter.java create mode 100644 src/java/org/apache/fop/pdf/PDFFilterException.java create mode 100644 src/java/org/apache/fop/pdf/PDFFont.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontDescriptor.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontNonBase14.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontTrueType.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontType0.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontType1.java create mode 100644 src/java/org/apache/fop/pdf/PDFFontType3.java create mode 100644 src/java/org/apache/fop/pdf/PDFFormXObject.java create mode 100644 src/java/org/apache/fop/pdf/PDFFunction.java create mode 100644 src/java/org/apache/fop/pdf/PDFGState.java create mode 100644 src/java/org/apache/fop/pdf/PDFGoTo.java create mode 100644 src/java/org/apache/fop/pdf/PDFGoToRemote.java create mode 100644 src/java/org/apache/fop/pdf/PDFICCStream.java create mode 100644 src/java/org/apache/fop/pdf/PDFImage.java create mode 100644 src/java/org/apache/fop/pdf/PDFInfo.java create mode 100644 src/java/org/apache/fop/pdf/PDFInternalLink.java create mode 100644 src/java/org/apache/fop/pdf/PDFLink.java create mode 100644 src/java/org/apache/fop/pdf/PDFNumber.java create mode 100644 src/java/org/apache/fop/pdf/PDFObject.java create mode 100644 src/java/org/apache/fop/pdf/PDFOutline.java create mode 100644 src/java/org/apache/fop/pdf/PDFPage.java create mode 100644 src/java/org/apache/fop/pdf/PDFPages.java create mode 100644 src/java/org/apache/fop/pdf/PDFPathPaint.java create mode 100644 src/java/org/apache/fop/pdf/PDFPattern.java create mode 100644 src/java/org/apache/fop/pdf/PDFRectangle.java create mode 100644 src/java/org/apache/fop/pdf/PDFResourceContext.java create mode 100644 src/java/org/apache/fop/pdf/PDFResources.java create mode 100644 src/java/org/apache/fop/pdf/PDFRoot.java create mode 100644 src/java/org/apache/fop/pdf/PDFShading.java create mode 100644 src/java/org/apache/fop/pdf/PDFState.java create mode 100644 src/java/org/apache/fop/pdf/PDFStream.java create mode 100644 src/java/org/apache/fop/pdf/PDFT1Stream.java create mode 100644 src/java/org/apache/fop/pdf/PDFTTFStream.java create mode 100644 src/java/org/apache/fop/pdf/PDFUri.java create mode 100644 src/java/org/apache/fop/pdf/PDFWArray.java create mode 100644 src/java/org/apache/fop/pdf/PDFXObject.java create mode 100644 src/java/org/apache/fop/pdf/StreamCache.java create mode 100644 src/java/org/apache/fop/pdf/TempFileStreamCache.java create mode 100644 src/java/org/apache/fop/pdf/TransitionDictionary.java create mode 100644 src/java/org/apache/fop/pdf/package.html create mode 100644 src/java/org/apache/fop/render/AbstractRenderer.java create mode 100644 src/java/org/apache/fop/render/PrintRenderer.java create mode 100644 src/java/org/apache/fop/render/Renderer.java create mode 100644 src/java/org/apache/fop/render/RendererContext.java create mode 100644 src/java/org/apache/fop/render/XMLHandler.java create mode 100644 src/java/org/apache/fop/render/awt/AWTFontMetrics.java create mode 100644 src/java/org/apache/fop/render/awt/AWTRenderer.java create mode 100644 src/java/org/apache/fop/render/awt/FontMetricsMapper.java create mode 100644 src/java/org/apache/fop/render/awt/FontSetup.java create mode 100644 src/java/org/apache/fop/render/package.html create mode 100644 src/java/org/apache/fop/render/pcl/PCLRenderer.java create mode 100644 src/java/org/apache/fop/render/pcl/PCLStream.java create mode 100644 src/java/org/apache/fop/render/pdf/CTMHelper.java create mode 100644 src/java/org/apache/fop/render/pdf/EmbedFontInfo.java create mode 100644 src/java/org/apache/fop/render/pdf/FontReader.java create mode 100644 src/java/org/apache/fop/render/pdf/FontSetup.java create mode 100644 src/java/org/apache/fop/render/pdf/FontTriplet.java create mode 100644 src/java/org/apache/fop/render/pdf/FopPDFImage.java create mode 100644 src/java/org/apache/fop/render/pdf/PDFRenderer.java create mode 100644 src/java/org/apache/fop/render/pdf/PDFXMLHandler.java create mode 100644 src/java/org/apache/fop/render/pdf/package.html create mode 100644 src/java/org/apache/fop/render/ps/ASCII85OutputStream.java create mode 100644 src/java/org/apache/fop/render/ps/ASCIIHexOutputStream.java create mode 100644 src/java/org/apache/fop/render/ps/DSCConstants.java create mode 100644 src/java/org/apache/fop/render/ps/Finalizable.java create mode 100644 src/java/org/apache/fop/render/ps/FlateEncodeOutputStream.java create mode 100644 src/java/org/apache/fop/render/ps/PSGenerator.java create mode 100644 src/java/org/apache/fop/render/ps/PSGraphics2D.java create mode 100644 src/java/org/apache/fop/render/ps/PSProcSets.java create mode 100644 src/java/org/apache/fop/render/ps/PSRenderer.java create mode 100644 src/java/org/apache/fop/render/ps/PSState.java create mode 100644 src/java/org/apache/fop/render/ps/PSTextElementBridge.java create mode 100644 src/java/org/apache/fop/render/ps/PSTextPainter.java create mode 100644 src/java/org/apache/fop/render/ps/PSXMLHandler.java create mode 100644 src/java/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java create mode 100644 src/java/org/apache/fop/render/svg/SVGRenderer.java create mode 100644 src/java/org/apache/fop/render/txt/TXTRenderer.java create mode 100644 src/java/org/apache/fop/render/txt/TXTStream.java create mode 100644 src/java/org/apache/fop/render/xml/XMLRenderer.java create mode 100644 src/java/org/apache/fop/render/xml/XMLXMLHandler.java create mode 100644 src/java/org/apache/fop/render/xml/package.html create mode 100644 src/java/org/apache/fop/rtf/renderer/RTFHandler.java create mode 100644 src/java/org/apache/fop/servlet/FopPrintServlet.java create mode 100644 src/java/org/apache/fop/servlet/FopServlet.java create mode 100644 src/java/org/apache/fop/servlet/package.html create mode 100644 src/java/org/apache/fop/svg/PDFAElementBridge.java create mode 100644 src/java/org/apache/fop/svg/PDFANode.java create mode 100644 src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java create mode 100644 src/java/org/apache/fop/svg/PDFGraphics2D.java create mode 100644 src/java/org/apache/fop/svg/PDFGraphicsConfiguration.javat create mode 100644 src/java/org/apache/fop/svg/PDFGraphicsDevice.java create mode 100644 src/java/org/apache/fop/svg/PDFImageElementBridge.java create mode 100644 src/java/org/apache/fop/svg/PDFTextElementBridge.java create mode 100644 src/java/org/apache/fop/svg/PDFTextPainter.java create mode 100644 src/java/org/apache/fop/svg/PDFTranscoder.java create mode 100644 src/java/org/apache/fop/svg/SVGElement.java create mode 100644 src/java/org/apache/fop/svg/SVGElementMapping.java create mode 100644 src/java/org/apache/fop/svg/SVGObj.java create mode 100644 src/java/org/apache/fop/svg/SVGUserAgent.java create mode 100644 src/java/org/apache/fop/svg/SVGUtilities.java create mode 100644 src/java/org/apache/fop/svg/package.html create mode 100644 src/java/org/apache/fop/tools/AreaTreeBuilder.java create mode 100644 src/java/org/apache/fop/tools/DocumentInputSource.java create mode 100644 src/java/org/apache/fop/tools/DocumentReader.java create mode 100644 src/java/org/apache/fop/tools/TestConverter.java create mode 100644 src/java/org/apache/fop/tools/anttasks/Compare.java create mode 100644 src/java/org/apache/fop/tools/anttasks/Fop.java create mode 100644 src/java/org/apache/fop/tools/anttasks/RunTest.java create mode 100644 src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java create mode 100644 src/java/org/apache/fop/tools/xslt/TraxTransform.java create mode 100644 src/java/org/apache/fop/tools/xslt/XSLTransform.java create mode 100644 src/java/org/apache/fop/traits/BlockProps.java create mode 100644 src/java/org/apache/fop/traits/BorderProps.java create mode 100644 src/java/org/apache/fop/traits/InlineProps.java create mode 100644 src/java/org/apache/fop/traits/LayoutProps.java create mode 100644 src/java/org/apache/fop/traits/SpaceVal.java create mode 100644 src/java/org/apache/fop/util/CharUtilities.java create mode 100644 src/java/org/apache/fop/util/StreamUtilities.java create mode 100644 src/java/org/apache/fop/viewer/Command.java create mode 100644 src/java/org/apache/fop/viewer/GoToPageDialog.java create mode 100644 src/java/org/apache/fop/viewer/PreviewDialog.java create mode 100644 src/java/org/apache/fop/viewer/PreviewDialogAboutBox.java create mode 100644 src/java/org/apache/fop/viewer/Translator.java create mode 100644 src/java/org/apache/fop/viewer/images/Print.gif create mode 100644 src/java/org/apache/fop/viewer/images/firstpg.gif create mode 100644 src/java/org/apache/fop/viewer/images/fop.gif create mode 100644 src/java/org/apache/fop/viewer/images/lastpg.gif create mode 100644 src/java/org/apache/fop/viewer/images/nextpg.gif create mode 100644 src/java/org/apache/fop/viewer/images/prevpg.gif create mode 100644 src/java/org/apache/fop/viewer/images/reload.gif create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_cs.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_de.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_fi.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_fr.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_it.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_ja.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_pl.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_ru.properties create mode 100644 src/java/org/apache/fop/viewer/resources/Viewer_tr.properties diff --git a/src/java/org/apache/fop/apps/AWTStarter.java b/src/java/org/apache/fop/apps/AWTStarter.java new file mode 100644 index 000000000..c621f8b0b --- /dev/null +++ b/src/java/org/apache/fop/apps/AWTStarter.java @@ -0,0 +1,152 @@ +/* + * $Id: AWTStarter.java,v 1.18 2003/02/27 10:13:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +//FOP +import org.apache.fop.render.awt.AWTRenderer; +import org.apache.fop.viewer.PreviewDialog; +import org.apache.fop.viewer.Translator; + +//Java +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Locale; + +// SAX +import org.xml.sax.XMLReader; + +/** + * AWT Viewer starter. + * Originally contributed by: + * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com + * Modified to use streaming API by Mark Lillywhite, mark-fop@inomial.com + */ +public class AWTStarter extends CommandLineStarter { + private PreviewDialog frame; + private Translator translator; + private Driver driver; + private XMLReader parser; + + /** + * Construct an AWTStarter + * @param commandLineOptions the parsed command line options + * @throws FOPException if anything goes wrong during initialization. + */ + public AWTStarter(CommandLineOptions commandLineOptions) + throws FOPException { + super(commandLineOptions); + init(); + } + + private void init() throws FOPException { + //Creates Translator according to the language + String language = commandLineOptions.getLanguage(); + if (language == null) { + translator = new Translator(Locale.getDefault()); + } else { + translator = new Translator(new Locale(language, "")); + } + AWTRenderer renderer = new AWTRenderer(translator); + frame = createPreviewDialog(renderer, translator); + renderer.setComponent(frame); + driver = new Driver(); + driver.setRenderer(renderer); + parser = inputHandler.getParser(); + if (parser == null) { + throw new FOPException("Unable to create SAX parser"); + } + } + + /** + * Runs formatting. + * @throws FOPException FIXME should not happen. + */ + public void run() throws FOPException { + driver.reset(); + try { + frame.setStatus(translator.getString("Status.Build.FO.tree")); + driver.render(parser, inputHandler.getInputSource()); + frame.setStatus(translator.getString("Status.Show")); + frame.showPage(); + } catch (Exception e) { + frame.reportException(e); + } + } + + private PreviewDialog createPreviewDialog(AWTRenderer renderer, + Translator res) { + PreviewDialog frame = new PreviewDialog(this, renderer, res); + frame.addWindowListener(new WindowAdapter() { + public void windowClosed(WindowEvent we) { + System.exit(0); + } + }); + + //Centers the window + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = frame.getSize(); + if (frameSize.height > screenSize.height) { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) { + frameSize.width = screenSize.width; + } + frame.setLocation((screenSize.width - frameSize.width) / 2, + (screenSize.height - frameSize.height) / 2); + frame.setVisible(true); + return frame; + } +} + diff --git a/src/java/org/apache/fop/apps/CommandLineOptions.java b/src/java/org/apache/fop/apps/CommandLineOptions.java new file mode 100644 index 000000000..23693494c --- /dev/null +++ b/src/java/org/apache/fop/apps/CommandLineOptions.java @@ -0,0 +1,725 @@ +/* + * $Id: CommandLineOptions.java,v 1.22 2003/02/27 10:13:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// java +import java.io.File; +import java.io.FileNotFoundException; + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; + +/** + * Options parses the commandline arguments + */ +public class CommandLineOptions { + + /* input / output not set */ + private static final int NOT_SET = 0; + /* input: fo file */ + private static final int FO_INPUT = 1; + /* input: xml+xsl file */ + private static final int XSLT_INPUT = 2; + /* output: pdf file */ + private static final int PDF_OUTPUT = 1; + /* output: screen using swing */ + private static final int AWT_OUTPUT = 2; + /* output: mif file */ + private static final int MIF_OUTPUT = 3; + /* output: sent swing rendered file to printer */ + private static final int PRINT_OUTPUT = 4; + /* output: pcl file */ + private static final int PCL_OUTPUT = 5; + /* output: postscript file */ + private static final int PS_OUTPUT = 6; + /* output: text file */ + private static final int TXT_OUTPUT = 7; + /* output: svg file */ + private static final int SVG_OUTPUT = 8; + /* output: XML area tree */ + private static final int AREA_OUTPUT = 9; + /* output: RTF file */ + private static final int RTF_OUTPUT = 10; + + /* show configuration information */ + private Boolean dumpConfiguration = Boolean.FALSE; + /* suppress any progress information */ + private Boolean quiet = Boolean.FALSE; + /* for area tree XML output, only down to block area level */ + private Boolean suppressLowLevelAreas = Boolean.FALSE; + /* user configuration file */ + private File userConfigFile = null; + /* input fo file */ + private File fofile = null; + /* xsltfile (xslt transformation as input) */ + private File xsltfile = null; + /* xml file (xslt transformation as input) */ + private File xmlfile = null; + /* output file */ + private File outfile = null; + /* input mode */ + private int inputmode = NOT_SET; + /* output mode */ + private int outputmode = NOT_SET; + /* language for user information */ + private String language = null; + + private java.util.HashMap rendererOptions; + + private Logger log; + + /** + * Construct a command line option object from command line arguments + * @param args command line parameters + * @throws FOPException for general errors + * @throws FileNotFoundException if an input file wasn't found. + */ + public CommandLineOptions(String[] args) + throws FOPException, FileNotFoundException { + + log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + + boolean optionsParsed = true; + rendererOptions = new java.util.HashMap(); + try { + optionsParsed = parseOptions(args); + if (optionsParsed) { + checkSettings(); + } + } catch (FOPException e) { + printUsage(); + throw e; + } catch (java.io.FileNotFoundException e) { + printUsage(); + throw e; + } + } + + /** + * Get the logger. + * @return the logger + */ + public Logger getLogger() { + return log; + } + + /** + * parses the commandline arguments + * @return true if parse was successful and processing can continue, false + * if processing should stop + * @exception FOPException if there was an error in the format of the options + */ + private boolean parseOptions(String args[]) throws FOPException { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-d") || args[i].equals("--full-error-dump")) { + log = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG); + } else if (args[i].equals("-x") + || args[i].equals("--dump-config")) { + dumpConfiguration = Boolean.TRUE; + } else if (args[i].equals("-q") || args[i].equals("--quiet")) { + quiet = Boolean.TRUE; + log = new ConsoleLogger(ConsoleLogger.LEVEL_ERROR); + } else if (args[i].equals("-c")) { + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("if you use '-c', you must specify " + + "the name of the configuration file"); + } else { + userConfigFile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-l")) { + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("if you use '-l', you must specify a language"); + } else { + language = args[i + 1]; + i++; + } + } else if (args[i].equals("-s")) { + suppressLowLevelAreas = Boolean.TRUE; + } else if (args[i].equals("-fo")) { + inputmode = FO_INPUT; + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the fo file for the '-fo' option"); + } else { + fofile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-xsl")) { + inputmode = XSLT_INPUT; + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the stylesheet " + + "file for the '-xsl' option"); + } else { + xsltfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-xml")) { + inputmode = XSLT_INPUT; + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the input file " + + "for the '-xml' option"); + } else { + xmlfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-awt")) { + setOutputMode(AWT_OUTPUT); + } else if (args[i].equals("-pdf")) { + setOutputMode(PDF_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the pdf output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-mif")) { + setOutputMode(MIF_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the mif output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-rtf")) { + setOutputMode(RTF_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the rtf output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-print")) { + setOutputMode(PRINT_OUTPUT); + // show print help + if (i + 1 < args.length) { + if (args[i + 1].equals("help")) { + printUsagePrintOutput(); + return false; + } + } + } else if (args[i].equals("-pcl")) { + setOutputMode(PCL_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the pdf output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-ps")) { + setOutputMode(PS_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the PostScript output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-txt")) { + setOutputMode(TXT_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the text output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].equals("-svg")) { + setOutputMode(SVG_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the svg output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else if (args[i].charAt(0) != '-') { + if (inputmode == NOT_SET) { + inputmode = FO_INPUT; + fofile = new File(args[i]); + } else if (outputmode == NOT_SET) { + outputmode = PDF_OUTPUT; + outfile = new File(args[i]); + } else { + throw new FOPException("Don't know what to do with " + + args[i]); + } + } else if (args[i].equals("-at")) { + setOutputMode(AREA_OUTPUT); + if ((i + 1 == args.length) + || (args[i + 1].charAt(0) == '-')) { + throw new FOPException("you must specify the area-tree output file"); + } else { + outfile = new File(args[i + 1]); + i++; + } + } else { + printUsage(); + return false; + } + } + return true; + } // end parseOptions + + private void setOutputMode(int mode) throws FOPException { + if (outputmode == NOT_SET) { + outputmode = mode; + } else { + throw new FOPException("you can only set one output method"); + } + } + + /** + * checks whether all necessary information has been given in a consistent way + */ + private void checkSettings() throws FOPException, FileNotFoundException { + if (inputmode == NOT_SET) { + throw new FOPException("No input file specified"); + } + + if (outputmode == NOT_SET) { + throw new FOPException("No output file specified"); + } + + if (inputmode == XSLT_INPUT) { + // check whether xml *and* xslt file have been set + if (xmlfile == null) { + throw new FOPException("XML file must be specified for the tranform mode"); + } + if (xsltfile == null) { + throw new FOPException("XSLT file must be specified for the tranform mode"); + } + + // warning if fofile has been set in xslt mode + if (fofile != null) { + log.warn("Can't use fo file with transform mode! Ignoring.\n" + + "Your input is " + "\n xmlfile: " + + xmlfile.getAbsolutePath() + + "\nxsltfile: " + + xsltfile.getAbsolutePath() + + "\n fofile: " + + fofile.getAbsolutePath()); + } + if (!xmlfile.exists()) { + throw new FileNotFoundException("xml file " + + xmlfile.getAbsolutePath() + + " not found "); + } + if (!xsltfile.exists()) { + throw new FileNotFoundException("xsl file " + + xsltfile.getAbsolutePath() + + " not found "); + } + + } else if (inputmode == FO_INPUT) { + if (xmlfile != null || xsltfile != null) { + log.warn("fo input mode, but xmlfile or xslt file are set:"); + log.error("xml file: " + xmlfile.toString()); + log.error("xslt file: " + xsltfile.toString()); + } + if (!fofile.exists()) { + throw new FileNotFoundException("fo file " + + fofile.getAbsolutePath() + + " not found "); + } + + } + } // end checkSettings + + /** + * @return the type chosen renderer + * @throws FOPException for invalid output modes + */ + public int getRenderer() throws FOPException { + switch (outputmode) { + case NOT_SET: + throw new FOPException("Renderer has not been set!"); + case PDF_OUTPUT: + return Driver.RENDER_PDF; + case AWT_OUTPUT: + return Driver.RENDER_AWT; + case MIF_OUTPUT: + return Driver.RENDER_MIF; + case PRINT_OUTPUT: + return Driver.RENDER_PRINT; + case PCL_OUTPUT: + return Driver.RENDER_PCL; + case PS_OUTPUT: + return Driver.RENDER_PS; + case TXT_OUTPUT: + return Driver.RENDER_TXT; + case SVG_OUTPUT: + return Driver.RENDER_SVG; + case AREA_OUTPUT: + rendererOptions.put("fineDetail", isCoarseAreaXml()); + return Driver.RENDER_XML; + case RTF_OUTPUT: + return Driver.RENDER_RTF; + default: + throw new FOPException("Invalid Renderer setting!"); + } + } + + /** + * Get the input handler. + * @return the input handler + */ + public InputHandler getInputHandler() { + switch (inputmode) { + case FO_INPUT: + return new FOInputHandler(fofile); + case XSLT_INPUT: + return new XSLTInputHandler(xmlfile, xsltfile); + default: + return new FOInputHandler(fofile); + } + } + + /** + * Get the renderer specific options. + * @return hash map with option/value pairs. + */ + public java.util.HashMap getRendererOptions() { + return rendererOptions; + } + + /** + * Get the starter for the process. + * @return the starter. + * @throws FOPException In case of failure while getting the starter + */ + public Starter getStarter() throws FOPException { + Starter starter = null; + switch (outputmode) { + case AWT_OUTPUT: + try { + starter = new AWTStarter(this); + } catch (FOPException e) { + throw e; + } catch (Exception e) { + throw new FOPException("AWTStarter could not be loaded.", e); + } + break; + case PRINT_OUTPUT: + try { + starter = new PrintStarter(this); + } catch (FOPException e) { + throw e; + } catch (Exception e) { + throw new FOPException("PrintStarter could not be loaded.", e); + } + break; + default: + starter = new CommandLineStarter(this); + } + starter.enableLogging(log); + return starter; + } + + /** + * Returns the input mode (type of input data, ex. NOT_SET or FO_INPUT) + * @return the input mode + */ + public int getInputMode() { + return inputmode; + } + + /** + * Returns the output mode (output format, ex. NOT_SET or PDF_OUTPUT) + * @return the output mode + */ + public int getOutputMode() { + return outputmode; + } + + /** + * Returns the XSL-FO file if set. + * @return the XSL-FO file, null if not set + */ + public File getFOFile() { + return fofile; + } + + /** + * Returns the input XML file if set. + * @return the input XML file, null if not set + */ + public File getXMLFile() { + return xmlfile; + } + + /** + * Returns the stylesheet to be used for transformation to XSL-FO. + * @return stylesheet + */ + public File getXSLFile() { + return xsltfile; + } + + /** + * Returns the output file + * @return the output file + */ + public File getOutputFile() { + return outfile; + } + + /** + * Returns the user configuration file to be used. + * @return the userconfig.xml file + */ + public File getUserConfigFile() { + return userConfigFile; + } + + /** + * Returns the default language + * @return the default language + */ + public String getLanguage() { + return language; + } + + /** + * Indicates if FOP should be silent. + * @return true if should be silent + */ + public Boolean isQuiet() { + return quiet; + } + + /** + * Indicates if FOP should dump its configuration during runtime. + * @return true if config dump is enabled + */ + public Boolean dumpConfiguration() { + return dumpConfiguration; + } + + /** + * Indicates whether the XML renderer should generate course area XML + * @return true if coarse area XML is desired + */ + public Boolean isCoarseAreaXml() { + return suppressLowLevelAreas; + } + + /** + * Returns the input file. + * @return either the fofile or the xmlfile + */ + public File getInputFile() { + switch (inputmode) { + case FO_INPUT: + return fofile; + case XSLT_INPUT: + return xmlfile; + default: + return fofile; + } + } + + /** + * shows the commandline syntax including a summary of all available options and some examples + */ + public static void printUsage() { + System.err.println( + "\nUSAGE\nFop [options] [-fo|-xml] infile [-xsl file] " + + "[-awt|-pdf|-mif|-rtf|-pcl|-ps|-txt|-at|-print] \n" + + " [OPTIONS] \n" + + " -d debug mode \n" + + " -x dump configuration settings \n" + + " -q quiet mode \n" + + " -c cfg.xml use additional configuration file cfg.xml\n" + + " -l lang the language to use for user information \n" + + " -s for area tree XML, down to block areas only\n\n" + + " [INPUT] \n" + + " infile xsl:fo input file (the same as the next) \n" + + " -fo infile xsl:fo input file \n" + + " -xml infile xml input file, must be used together with -xsl \n" + + " -xsl stylesheet xslt stylesheet \n \n" + + " [OUTPUT] \n" + + " outfile input will be rendered as pdf file into outfile \n" + + " -pdf outfile input will be rendered as pdf file (outfile req'd) \n" + + " -awt input will be displayed on screen \n" + + " -mif outfile input will be rendered as mif file (outfile req'd)\n" + + " -rtf outfile input will be rendered as rtf file (outfile req'd)\n" + + " -pcl outfile input will be rendered as pcl file (outfile req'd) \n" + + " -ps outfile input will be rendered as PostScript file (outfile req'd) \n" + + " -txt outfile input will be rendered as text file (outfile req'd) \n" + + " -svg outfile input will be rendered as an svg slides file (outfile req'd) \n" + + " -at outfile representation of area tree as XML (outfile req'd) \n" + + " -print input file will be rendered and sent to the printer \n" + + " see options with \"-print help\" \n\n" + + " [Examples]\n" + " Fop foo.fo foo.pdf \n" + + " Fop -fo foo.fo -pdf foo.pdf (does the same as the previous line)\n" + + " Fop -xsl foo.xsl -xml foo.xml -pdf foo.pdf\n" + + " Fop foo.fo -mif foo.mif\n" + + " Fop foo.fo -rtf foo.rtf\n" + + " Fop foo.fo -print or Fop -print foo.fo \n" + + " Fop foo.fo -awt \n"); + } + + /** + * shows the options for print output + */ + public void printUsagePrintOutput() { + System.err.println("USAGE: -print [-Dstart=i] [-Dend=i] [-Dcopies=i] [-Deven=true|false] " + + " org.apache.fop.apps.Fop (..) -print \n" + + "Example:\n" + + "java -Dstart=1 -Dend=2 org.apache.Fop.apps.Fop infile.fo -print "); + } + + + /** + * debug mode. outputs all commandline settings + */ + private void debug() { + log.debug("Input mode: "); + switch (inputmode) { + case NOT_SET: + log.debug("not set"); + break; + case FO_INPUT: + log.debug("FO "); + log.debug("fo input file: " + fofile.toString()); + break; + case XSLT_INPUT: + log.debug("xslt transformation"); + log.debug("xml input file: " + xmlfile.toString()); + log.debug("xslt stylesheet: " + xsltfile.toString()); + break; + default: + log.debug("unknown input type"); + } + log.debug("Output mode: "); + switch (outputmode) { + case NOT_SET: + log.debug("not set"); + break; + case PDF_OUTPUT: + log.debug("pdf"); + log.debug("output file: " + outfile.toString()); + break; + case AWT_OUTPUT: + log.debug("awt on screen"); + if (outfile != null) { + log.error("awt mode, but outfile is set:"); + log.debug("out file: " + outfile.toString()); + } + break; + case MIF_OUTPUT: + log.debug("mif"); + log.debug("output file: " + outfile.toString()); + break; + case RTF_OUTPUT: + log.debug("rtf"); + log.debug("output file: " + outfile.toString()); + break; + case PRINT_OUTPUT: + log.debug("print directly"); + if (outfile != null) { + log.error("print mode, but outfile is set:"); + log.error("out file: " + outfile.toString()); + } + break; + case PCL_OUTPUT: + log.debug("pcl"); + log.debug("output file: " + outfile.toString()); + break; + case PS_OUTPUT: + log.debug("PostScript"); + log.debug("output file: " + outfile.toString()); + break; + case TXT_OUTPUT: + log.debug("txt"); + log.debug("output file: " + outfile.toString()); + break; + case SVG_OUTPUT: + log.debug("svg"); + log.debug("output file: " + outfile.toString()); + break; + default: + log.debug("unknown input type"); + } + + + log.debug("OPTIONS"); + if (userConfigFile != null) { + log.debug("user configuration file: " + + userConfigFile.toString()); + } else { + log.debug("no user configuration file is used [default]"); + } + if (dumpConfiguration != null) { + log.debug("dump configuration"); + } else { + log.debug("don't dump configuration [default]"); + } + if (quiet != null) { + log.debug("quiet mode on"); + } else { + log.debug("quiet mode off [default]"); + } + + } + +} + diff --git a/src/java/org/apache/fop/apps/CommandLineStarter.java b/src/java/org/apache/fop/apps/CommandLineStarter.java new file mode 100644 index 000000000..cdda837b3 --- /dev/null +++ b/src/java/org/apache/fop/apps/CommandLineStarter.java @@ -0,0 +1,122 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// SAX +import org.xml.sax.XMLReader; + +// Java +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; + + +/** + * super class for all classes which start Fop from the commandline + * + * Modified to use new streaming API by Mark Lillywhite, mark-fop@inomial.com + */ +public class CommandLineStarter extends Starter { + + /** the command-line options associated with this starter */ + protected CommandLineOptions commandLineOptions; + + /** + * Main constructor + * @param commandLineOptions command-line options to use + * @throws FOPException In case of failure + */ + public CommandLineStarter(CommandLineOptions commandLineOptions) + throws FOPException { + this.commandLineOptions = commandLineOptions; + super.setInputHandler(commandLineOptions.getInputHandler()); + } + + /** + * Run the format. + * @exception FOPException if there is an error during processing + */ + public void run() throws FOPException { + String version = Version.getVersion(); + + getLogger().info(version); + + XMLReader parser = inputHandler.getParser(); + setParserFeatures(parser); + + Driver driver = new Driver(); + setupLogger(driver); + driver.initialize(); + + try { + driver.setRenderer(commandLineOptions.getRenderer()); + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream( + commandLineOptions.getOutputFile())); + try { + driver.setOutputStream(bos); + if (driver.getRenderer() != null) { + driver.getRenderer().setOptions( + commandLineOptions.getRendererOptions()); + } + driver.render(parser, inputHandler.getInputSource()); + } finally { + bos.close(); + } + System.exit(0); + } catch (Exception e) { + if (e instanceof FOPException) { + throw (FOPException) e; + } + throw new FOPException(e); + } + } + +} + diff --git a/src/java/org/apache/fop/apps/Driver.java b/src/java/org/apache/fop/apps/Driver.java new file mode 100644 index 000000000..c8522bc74 --- /dev/null +++ b/src/java/org/apache/fop/apps/Driver.java @@ -0,0 +1,748 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// FOP +import org.apache.fop.fo.ElementMapping; +import org.apache.fop.fo.FOTreeBuilder; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.render.Renderer; +import org.apache.fop.tools.DocumentInputSource; +import org.apache.fop.tools.DocumentReader; + + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.LogEnabled; +import org.apache.avalon.framework.logger.Logger; + +// DOM +import org.w3c.dom.Document; + +// SAX +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import javax.xml.parsers.ParserConfigurationException; + +// Java +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * Primary class that drives overall FOP process. + *

+ * The simplest way to use this is to instantiate it with the + * InputSource and OutputStream, then set the renderer desired, and + * calling run(); + *

+ * Here is an example use of Driver which outputs PDF: + * + *

+ * Driver driver = new Driver(new InputSource (args[0]),
+ * new FileOutputStream(args[1]));
+ * driver.enableLogging(myLogger); //optional
+ * driver.setRenderer(RENDER_PDF);
+ * driver.run();
+ * 
+ * If neccessary, calling classes can call into the lower level + * methods to setup and + * render. Methods can be called to set the + * Renderer to use, the (possibly multiple) ElementMapping(s) to + * use and the OutputStream to use to output the results of the + * rendering (where applicable). In the case of the Renderer and + * ElementMapping(s), the Driver may be supplied either with the + * object itself, or the name of the class, in which case Driver will + * instantiate the class itself. The advantage of the latter is it + * enables runtime determination of Renderer and ElementMapping(s). + *

+ * Once the Driver is set up, the render method + * is called. Depending on whether DOM or SAX is being used, the + * invocation of the method is either render(Document) or + * buildFOTree(Parser, InputSource) respectively. + *

+ * A third possibility may be used to build the FO Tree, namely + * calling getContentHandler() and firing the SAX events yourself. + *

+ * Once the FO Tree is built, the format() and render() methods may be + * called in that order. + *

+ * Here is an example use of Driver which outputs to AWT: + * + *

+ * Driver driver = new Driver();
+ * driver.enableLogging(myLogger); //optional
+ * driver.setRenderer(new org.apache.fop.render.awt.AWTRenderer(translator));
+ * driver.render(parser, fileInputSource(args[0]));
+ * 
+ */ +public class Driver implements LogEnabled { + + /** + * Render to PDF. OutputStream must be set + */ + public static final int RENDER_PDF = 1; + + /** + * Render to a GUI window. No OutputStream neccessary + */ + public static final int RENDER_AWT = 2; + + /** + * Render to MIF. OutputStream must be set + */ + public static final int RENDER_MIF = 3; + + /** + * Render to XML. OutputStream must be set + */ + public static final int RENDER_XML = 4; + + /** + * Render to PRINT. No OutputStream neccessary + */ + public static final int RENDER_PRINT = 5; + + /** + * Render to PCL. OutputStream must be set + */ + public static final int RENDER_PCL = 6; + + /** + * Render to Postscript. OutputStream must be set + */ + public static final int RENDER_PS = 7; + + /** + * Render to Text. OutputStream must be set + */ + public static final int RENDER_TXT = 8; + + /** + * Render to SVG. OutputStream must be set + */ + public static final int RENDER_SVG = 9; + + /** + * Render to RTF. OutputStream must be set + */ + public static final int RENDER_RTF = 10; + + /** + * the FO tree builder + */ + private FOTreeBuilder treeBuilder; + + /** + * the renderer type code given by setRenderer + */ + private int rendererType; + + /** + * the renderer to use to output the area tree + */ + private Renderer renderer; + + /** + * the structure handler + */ + private StructureHandler structHandler; + + /** + * the source of the FO file + */ + private InputSource source; + + /** + * the stream to use to output the results of the renderer + */ + private OutputStream stream; + + /** + * The XML parser to use when building the FO tree + */ + private XMLReader reader; + + /** + * the system resources that FOP will use + */ + private Logger log = null; + private FOUserAgent userAgent = null; + + /** + * Returns the fully qualified classname of the standard XML parser for FOP + * to use. + * @return the XML parser classname + */ + public static final String getParserClassName() { + try { + return javax.xml.parsers.SAXParserFactory.newInstance() + .newSAXParser().getXMLReader().getClass().getName(); + } catch (javax.xml.parsers.ParserConfigurationException e) { + return null; + } catch (org.xml.sax.SAXException e) { + return null; + } + } + + /** + * Main constructor for the Driver class. + */ + public Driver() { + stream = null; + } + + /** + * Convenience constructor for directly setting input and output. + * @param source InputSource to take the XSL-FO input from + * @param stream Target output stream + */ + public Driver(InputSource source, OutputStream stream) { + this(); + this.source = source; + this.stream = stream; + } + + /** + * Initializes the Driver object. + */ + public void initialize() { + stream = null; + treeBuilder = new FOTreeBuilder(); + treeBuilder.setUserAgent(getUserAgent()); + setupDefaultMappings(); + } + + /** + * Optionally sets the FOUserAgent instance for FOP to use. The Driver + * class sets up its own FOUserAgent if none is set through this method. + * @param agent FOUserAgent to use + */ + public void setUserAgent(FOUserAgent agent) { + userAgent = agent; + } + + private FOUserAgent getUserAgent() { + if (userAgent == null) { + userAgent = new FOUserAgent(); + userAgent.enableLogging(getLogger()); + userAgent.setBaseURL(""); + } + return userAgent; + } + + /** + * Provide the Driver instance with a logger. More information on Avalon + * logging can be found at the + * Avalon site. + * + * @param log the logger. Must not be null. + * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(Logger) + */ + public void enableLogging(Logger log) { + if (this.log == null) { + this.log = log; + } else { + getLogger().warn("Logger is already set! Won't use the new logger."); + } + } + + + /** + * Returns the logger for use by FOP. + * @return the logger + * @see #enableLogging(Logger) + */ + protected Logger getLogger() { + if (this.log == null) { + this.log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + this.log.error("Logger not set. Using ConsoleLogger as default."); + } + + return this.log; + } + + /** + * Resets the Driver so it can be reused. Property and element + * mappings are reset to defaults. + * The output stream is cleared. The renderer is cleared. + */ + public synchronized void reset() { + source = null; + stream = null; + reader = null; + treeBuilder.reset(); + } + + /** + * Indicates whether FOP has already received input data. + * @return true, if input data was received + */ + public boolean hasData() { + return (treeBuilder.hasData()); + } + + /** + * Set the OutputStream to use to output the result of the Renderer + * (if applicable) + * @param stream the stream to output the result of rendering to + */ + public void setOutputStream(OutputStream stream) { + this.stream = stream; + } + + /** + * Set the source for the FO document. This can be a normal SAX + * InputSource, or an DocumentInputSource containing a DOM document. + * @see DocumentInputSource + */ + public void setInputSource(InputSource source) { + this.source = source; + } + + /** + * Sets the reader used when reading in the source. If not set, + * this defaults to a basic SAX parser. + * @param reader the reader to use. + */ + public void setXMLReader(XMLReader reader) { + this.reader = reader; + } + + /** + * Sets all the element and property list mappings to their default values. + * + */ + public void setupDefaultMappings() { + addElementMapping("org.apache.fop.fo.FOElementMapping"); + addElementMapping("org.apache.fop.svg.SVGElementMapping"); + addElementMapping("org.apache.fop.extensions.ExtensionElementMapping"); + + // add mappings from available services + Iterator providers = + Service.providers(org.apache.fop.fo.ElementMapping.class); + if (providers != null) { + while (providers.hasNext()) { + String str = (String)providers.next(); + try { + addElementMapping(str); + } catch (IllegalArgumentException e) { + getLogger().warn("Error while adding element mapping", e); + } + + } + } + } + + /** + * Shortcut to set the rendering type to use. Must be one of + *
    + *
  • RENDER_PDF
  • + *
  • RENDER_AWT
  • + *
  • RENDER_MIF
  • + *
  • RENDER_XML
  • + *
  • RENDER_PCL
  • + *
  • RENDER_PS
  • + *
  • RENDER_TXT
  • + *
  • RENDER_SVG
  • + *
  • RENDER_RTF
  • + *
+ * @param renderer the type of renderer to use + * @throws IllegalArgumentException if an unsupported renderer type was required. + */ + public void setRenderer(int renderer) throws IllegalArgumentException { + rendererType = renderer; + switch (renderer) { + case RENDER_PDF: + setRenderer("org.apache.fop.render.pdf.PDFRenderer"); + break; + case RENDER_AWT: + throw new IllegalArgumentException("Use renderer form of setRenderer() for AWT"); + case RENDER_PRINT: + throw new IllegalArgumentException("Use renderer form of setRenderer() for PRINT"); + case RENDER_PCL: + setRenderer("org.apache.fop.render.pcl.PCLRenderer"); + break; + case RENDER_PS: + setRenderer("org.apache.fop.render.ps.PSRenderer"); + break; + case RENDER_TXT: + setRenderer("org.apache.fop.render.txt.TXTRenderer()"); + break; + case RENDER_MIF: + //structHandler will be set later + break; + case RENDER_XML: + setRenderer("org.apache.fop.render.xml.XMLRenderer"); + break; + case RENDER_SVG: + setRenderer("org.apache.fop.render.svg.SVGRenderer"); + break; + case RENDER_RTF: + //structHandler will be set later + break; + default: + throw new IllegalArgumentException("Unknown renderer type"); + } + } + + /** + * Set the Renderer to use. + * @param renderer the renderer instance to use (Note: Logger must be set at this point) + */ + public void setRenderer(Renderer renderer) { + renderer.setUserAgent(getUserAgent()); + this.renderer = renderer; + } + + /** + * Returns the currently active renderer. + * @return the renderer + */ + public Renderer getRenderer() { + return renderer; + } + + /** + * Sets the renderer. + * @param rendererClassName the fully qualified classname of the renderer + * class to use. + * @param version version number + * @deprecated use renderer.setProducer(version) + setRenderer(renderer) or + * just setRenderer(rendererType) which will use the default producer string. + * @see #setRenderer(int) + * @see #setRenderer(Renderer) + */ + public void setRenderer(String rendererClassName, String version) { + setRenderer(rendererClassName); + } + + /** + * Set the class name of the Renderer to use as well as the + * producer string for those renderers that can make use of it. + * @param rendererClassName classname of the renderer to use such as + * "org.apache.fop.render.pdf.PDFRenderer" + * @exception IllegalArgumentException if the classname was invalid. + * @see #setRenderer(int) + */ + public void setRenderer(String rendererClassName) + throws IllegalArgumentException { + try { + renderer = + (Renderer)Class.forName(rendererClassName).newInstance(); + if (renderer instanceof LogEnabled) { + ((LogEnabled)renderer).enableLogging(getLogger()); + } + renderer.setProducer(Version.getVersion()); + renderer.setUserAgent(getUserAgent()); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Could not find " + + rendererClassName); + } catch (InstantiationException e) { + throw new IllegalArgumentException("Could not instantiate " + + rendererClassName); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Could not access " + + rendererClassName); + } catch (ClassCastException e) { + throw new IllegalArgumentException(rendererClassName + + " is not a renderer"); + } + } + + /** + * Add the given element mapping. + * An element mapping maps element names to Java classes. + * + * @param mapping the element mappingto add + */ + public void addElementMapping(ElementMapping mapping) { + mapping.addToBuilder(treeBuilder); + } + + /** + * Add the element mapping with the given class name. + * @param mappingClassName the class name representing the element mapping. + * @throws IllegalArgumentException if there was not such element mapping. + */ + public void addElementMapping(String mappingClassName) + throws IllegalArgumentException { + try { + ElementMapping mapping = + (ElementMapping)Class.forName(mappingClassName).newInstance(); + addElementMapping(mapping); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Could not find " + + mappingClassName); + } catch (InstantiationException e) { + throw new IllegalArgumentException("Could not instantiate " + + mappingClassName); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Could not access " + + mappingClassName); + } catch (ClassCastException e) { + throw new IllegalArgumentException(mappingClassName + + " is not an ElementMapping"); + } + } + + /** + * Returns the tree builder (a SAX ContentHandler). + * + * Used in situations where SAX is used but not via a FOP-invoked + * SAX parser. A good example is an XSLT engine that fires SAX + * events but isn't a SAX Parser itself. + * @return a content handler for handling the SAX events. + */ + public ContentHandler getContentHandler() { + // TODO: - do this stuff in a better way + // PIJ: I guess the structure handler should be created by the renderer. + if (rendererType == RENDER_MIF) { + structHandler = new org.apache.fop.mif.MIFHandler(stream); + } else if (rendererType == RENDER_RTF) { + structHandler = new org.apache.fop.rtf.renderer.RTFHandler(stream); + } else { + if (renderer == null) { + throw new IllegalStateException( + "Renderer not set when using standard structHandler"); + } + structHandler = new LayoutHandler(stream, renderer, true); + } + + structHandler.enableLogging(getLogger()); + + treeBuilder.setUserAgent(getUserAgent()); + treeBuilder.setStructHandler(structHandler); + + return treeBuilder; + } + + /** + * Render the FO document read by a SAX Parser from an InputSource. + * @param parser the SAX parser. + * @param source the input source the parser reads from. + * @throws FOPException if anything goes wrong. + */ + public synchronized void render(XMLReader parser, InputSource source) + throws FOPException { + parser.setContentHandler(getContentHandler()); + try { + parser.parse(source); + } catch (SAXException e) { + if (e.getException() instanceof FOPException) { + // Undo exception tunneling. + throw (FOPException)e.getException(); + } else { + throw new FOPException(e); + } + } catch (IOException e) { + throw new FOPException(e); + } + } + + /** + * Render the FO ducument represented by a DOM Document. + * @param document the DOM document to read from + * @throws FOPException if anything goes wrong. + */ + public synchronized void render(Document document) + throws FOPException { + try { + DocumentInputSource source = new DocumentInputSource(document); + DocumentReader reader = new DocumentReader(); + reader.setContentHandler(getContentHandler()); + reader.parse(source); + } catch (SAXException e) { + if (e.getException() instanceof FOPException) { + // Undo exception tunneling. + throw (FOPException)e.getException(); + } else { + throw new FOPException(e); + } + } catch (IOException e) { + throw new FOPException(e); + } + + } + + /** + * Runs the formatting and renderering process using the previously set + * parser, input source, renderer and output stream. + * If the renderer was not set, default to PDF. + * If no parser was set, and the input source is not a dom document, + * get a default SAX parser. + * @throws IOException in case of IO errors. + * @throws FOPException if anything else goes wrong. + */ + public synchronized void run() throws IOException, FOPException { + if (renderer == null) { + setRenderer(RENDER_PDF); + } + + if (source == null) { + throw new FOPException("InputSource is not set."); + } + + if (reader == null) { + if (!(source instanceof DocumentInputSource)) { + try { + reader = javax.xml.parsers.SAXParserFactory.newInstance() + .newSAXParser().getXMLReader(); + } catch (SAXException e) { + throw new FOPException(e); + } catch (ParserConfigurationException e) { + throw new FOPException(e); + } + } + } + + if (source instanceof DocumentInputSource) { + render(((DocumentInputSource)source).getDocument()); + } else { + render(reader, source); + } + } + +} + +// code stolen from org.apache.batik.util and modified slightly +// does what sun.misc.Service probably does, but it cannot be relied on. +// hopefully will be part of standard jdk sometime. + +/** + * This class loads services present in the class path. + */ +class Service { + + private static Map providerMap = new java.util.Hashtable(); + + public static synchronized Iterator providers(Class cls) { + ClassLoader cl = cls.getClassLoader(); + // null if loaded by bootstrap class loader + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + String serviceFile = "META-INF/services/" + cls.getName(); + + // getLogger().debug("File: " + serviceFile); + + List lst = (List)providerMap.get(serviceFile); + if (lst != null) { + return lst.iterator(); + } + + lst = new java.util.Vector(); + providerMap.put(serviceFile, lst); + + Enumeration e; + try { + e = cl.getResources(serviceFile); + } catch (IOException ioe) { + return lst.iterator(); + } + + while (e.hasMoreElements()) { + try { + java.net.URL u = (java.net.URL)e.nextElement(); + //getLogger().debug("URL: " + u); + + InputStream is = u.openStream(); + Reader r = new InputStreamReader(is, "UTF-8"); + BufferedReader br = new BufferedReader(r); + + String line = br.readLine(); + while (line != null) { + try { + // First strip any comment... + int idx = line.indexOf('#'); + if (idx != -1) { + line = line.substring(0, idx); + } + + // Trim whitespace. + line = line.trim(); + + // If nothing left then loop around... + if (line.length() == 0) { + line = br.readLine(); + continue; + } + // getLogger().debug("Line: " + line); + + // Try and load the class + // Object obj = cl.loadClass(line).newInstance(); + // stick it into our vector... + lst.add(line); + } catch (Exception ex) { + // Just try the next line + } + + line = br.readLine(); + } + } catch (Exception ex) { + // Just try the next file... + } + + } + return lst.iterator(); + } + +} + diff --git a/src/java/org/apache/fop/apps/FOInputHandler.java b/src/java/org/apache/fop/apps/FOInputHandler.java new file mode 100644 index 000000000..403e96527 --- /dev/null +++ b/src/java/org/apache/fop/apps/FOInputHandler.java @@ -0,0 +1,104 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Imported SAX classes +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +// java +import java.io.File; +import java.net.URL; + +/** + * Manages input if it is an XSL-FO file. + */ +public class FOInputHandler extends InputHandler { + + private File fofile = null; + private URL foURL = null; + + /** + * Create a FOInputHandler for a file. + * @param fofile the file to read the FO document. + */ + public FOInputHandler(File fofile) { + this.fofile = fofile; + } + + /** + * Create a FOInputHandler for an URL. + * @param url the URL to read the FO document. + */ + public FOInputHandler(URL url) { + this.foURL = url; + } + + + /** + * @see org.apache.fop.apps.InputHandler#getInputSource() + */ + public InputSource getInputSource () { + if (fofile != null) { + return super.fileInputSource(fofile); + } + return super.urlInputSource(foURL); + } + + /** + * @see org.apache.fop.apps.InputHandler#getParser() + */ + public XMLReader getParser() throws FOPException { + return super.createParser(); + } + +} + diff --git a/src/java/org/apache/fop/apps/FOPException.java b/src/java/org/apache/fop/apps/FOPException.java new file mode 100644 index 000000000..cb8c4ca9c --- /dev/null +++ b/src/java/org/apache/fop/apps/FOPException.java @@ -0,0 +1,150 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +import org.xml.sax.SAXException; + +/** + * Exception thrown when FOP has a problem. + */ +public class FOPException extends Exception { + + private static final String EXCEPTION_SEPARATOR = "\n---------\n"; + + private Throwable exception; + + /** + * create a new FOP Exception + * + * @param message descriptive message + */ + public FOPException(String message) { + super(message); + } + + public FOPException(Throwable e) { + super(e.getMessage()); + setException(e); + } + + public FOPException(String message, Throwable e) { + super(message); + setException(e); + } + + protected void setException(Throwable t) { + exception = t; + } + + public Throwable getException() { + return exception; + } + + protected Throwable getRootException() { + Throwable result = exception; + + if (result instanceof SAXException) { + result = ((SAXException)result).getException(); + } + if (result instanceof java.lang.reflect.InvocationTargetException) { + result = + ((java.lang.reflect.InvocationTargetException)result).getTargetException(); + } + if (result != exception) { + return result; + } + return null; + } + + + public void printStackTrace() { + synchronized (System.err) { + super.printStackTrace(); + if (exception != null) { + System.err.println(EXCEPTION_SEPARATOR); + exception.printStackTrace(); + } + if (getRootException() != null) { + System.err.println(EXCEPTION_SEPARATOR); + getRootException().printStackTrace(); + } + } + } + + public void printStackTrace(java.io.PrintStream stream) { + synchronized (stream) { + super.printStackTrace(stream); + if (exception != null) { + stream.println(EXCEPTION_SEPARATOR); + exception.printStackTrace(stream); + } + if (getRootException() != null) { + stream.println(EXCEPTION_SEPARATOR); + getRootException().printStackTrace(stream); + } + } + } + + public void printStackTrace(java.io.PrintWriter writer) { + synchronized (writer) { + super.printStackTrace(writer); + if (exception != null) { + writer.println(EXCEPTION_SEPARATOR); + exception.printStackTrace(writer); + } + if (getRootException() != null) { + writer.println(EXCEPTION_SEPARATOR); + getRootException().printStackTrace(writer); + } + } + } + +} diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java new file mode 100644 index 000000000..a09ef5957 --- /dev/null +++ b/src/java/org/apache/fop/apps/Fop.java @@ -0,0 +1,91 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +/** + * The main application class for the FOP command line interface (CLI). + */ +public class Fop { + + /** + * The main routine for the command line interface + * @param args the command line parameters + */ + public static void main(String[] args) { + CommandLineOptions options = null; + + try { + options = new CommandLineOptions(args); + Starter starter = options.getStarter(); + starter.run(); + } catch (FOPException e) { + if (e.getMessage() == null) { + System.err.println("Exception occured with a null error message"); + } else { + System.err.println("" + e.getMessage()); + } + if (options != null && options.getLogger().isDebugEnabled()) { + e.printStackTrace(); + } else { + System.err.println("Turn on debugging for more information"); + } + } catch (java.io.FileNotFoundException e) { + System.err.println("" + e.getMessage()); + if (options != null && options.getLogger().isDebugEnabled()) { + e.printStackTrace(); + } else { + System.err.println("Turn on debugging for more information"); + } + } + } + +} + diff --git a/src/java/org/apache/fop/apps/InputHandler.java b/src/java/org/apache/fop/apps/InputHandler.java new file mode 100644 index 000000000..75cd81705 --- /dev/null +++ b/src/java/org/apache/fop/apps/InputHandler.java @@ -0,0 +1,133 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// SAX +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; + +// Java +import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.net.URL; +import java.io.File; + +/** + * Abstract super class for input handlers. + * Should be used to abstract the various possibilities on how input + * can be provided to FOP (but actually isn't). + */ +public abstract class InputHandler { + + /** + * Get the input source associated with this input handler. + * @return the input source + */ + public abstract InputSource getInputSource(); + + /** + * Get the SAX parser associated with this input handler. + * @return the SAX parser + * @throws FOPException in case of an error determining the SAX parser + */ + public abstract XMLReader getParser() throws FOPException; + + /** + * Creates an InputSource from a URL. + * @param url URL to use + * @return the newly created InputSource + */ + public static InputSource urlInputSource(URL url) { + return new InputSource(url.toString()); + } + + /** + * Creates an InputSource from a File + * @param file the File + * @return the InputSource created + */ + public static InputSource fileInputSource(File file) { + /* this code adapted from James Clark's in XT */ + String path = file.getAbsolutePath(); + String fSep = System.getProperty("file.separator"); + if (fSep != null && fSep.length() == 1) { + path = path.replace(fSep.charAt(0), '/'); + } + if (path.length() > 0 && path.charAt(0) != '/') { + path = '/' + path; + } + try { + return new InputSource(new URL("file", null, path).toString()); + } catch (java.net.MalformedURLException e) { + throw new Error("unexpected MalformedURLException"); + } + } + + /** + * Creates XMLReader object using default + * SAXParserFactory + * @return the created XMLReader + * @throws FOPException if the parser couldn't be created or configured for proper operation. + */ + protected static XMLReader createParser() throws FOPException { + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + return factory.newSAXParser().getXMLReader(); + } catch (SAXException se) { + throw new FOPException("Coudn't create XMLReader", se); + } catch (ParserConfigurationException pce) { + throw new FOPException("Coudn't create XMLReader", pce); + } + } +} + diff --git a/src/java/org/apache/fop/apps/LayoutHandler.java b/src/java/org/apache/fop/apps/LayoutHandler.java new file mode 100644 index 000000000..cc687cd23 --- /dev/null +++ b/src/java/org/apache/fop/apps/LayoutHandler.java @@ -0,0 +1,312 @@ +/* + * $Id: LayoutHandler.java,v 1.12 2003/02/27 10:13:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; + +// SAX +import org.xml.sax.SAXException; + +// FOP +import org.apache.fop.area.AreaTree; +import org.apache.fop.area.AreaTreeModel; +import org.apache.fop.area.StorePagesModel; +import org.apache.fop.area.Title; +import org.apache.fop.area.TreeExt; +import org.apache.fop.fo.pagination.LayoutMasterSet; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.render.Renderer; + +/** + * Layout handler that receives the structure events. + * This initiates layout processes and corresponding + * rendering processes such as start/end. + */ +public class LayoutHandler extends StructureHandler { + + // TODO: Collecting of statistics should be configurable + private final boolean collectStatistics = true; + private static final boolean MEM_PROFILE_WITH_GC = false; + + /** + * Somewhere to get our stats from. + */ + private Runtime runtime; + + /** + * Keep track of the number of pages rendered. + */ + private int pageCount; + + /** + * Keep track of heap memory allocated, + * for statistical purposes. + */ + private long initialMemory; + + /** + * Keep track of time used by renderer. + */ + private long startTime; + + /** + * The stream to which this rendering is to be + * written to. Note that some renderers + * do not render to a stream, and that this + * member can therefore be null. + */ + private OutputStream outputStream; + + /** + * The renderer being used. + */ + private Renderer renderer; + + /** + * The FontInfo for this renderer. + */ + private FontInfo fontInfo = new FontInfo(); + + /** + * The current AreaTree for the PageSequence being rendered. + */ + private AreaTree areaTree; + private AreaTreeModel atModel; + + /** + * Main constructor + * @param outputStream the stream that the result is rendered to + * @param renderer the renderer to call + * @param store if true then use the store pages model and keep the + * area tree in memory + */ + public LayoutHandler(OutputStream outputStream, Renderer renderer, + boolean store) { + if (collectStatistics) { + runtime = Runtime.getRuntime(); + } + this.outputStream = outputStream; + this.renderer = renderer; + + this.areaTree = new AreaTree(); + this.atModel = AreaTree.createRenderPagesModel(renderer); + //this.atModel = new CachedRenderPagesModel(renderer); + areaTree.setTreeModel(atModel); + } + + /** + * Get the area tree for this layout handler. + * + * @return the area tree for this document + */ + public AreaTree getAreaTree() { + return areaTree; + } + + /** + * Start the document. + * This starts the document in the renderer. + * + * @throws SAXException if there is an error + */ + public void startDocument() throws SAXException { + //Initialize statistics + if (collectStatistics) { + pageCount = 0; + if (MEM_PROFILE_WITH_GC) { + System.gc(); // This takes time but gives better results + } + + initialMemory = runtime.totalMemory() - runtime.freeMemory(); + startTime = System.currentTimeMillis(); + } + try { + renderer.setupFontInfo(fontInfo); + // check that the "any,normal,400" font exists + if (!fontInfo.isSetupValid()) { + throw new SAXException(new FOPException( + "No default font defined by OutputConverter")); + } + renderer.startRenderer(outputStream); + } catch (IOException e) { + throw new SAXException(e); + } + } + + /** + * End the document. + * + * @throws SAXException if there is some error + */ + public void endDocument() throws SAXException { + try { + //processAreaTree(atModel); + areaTree.endDocument(); + renderer.stopRenderer(); + } catch (Exception e) { + throw new SAXException(e); + } + + if (collectStatistics) { + if (MEM_PROFILE_WITH_GC) { + // This takes time but gives better results + System.gc(); + } + long memoryNow = runtime.totalMemory() - runtime.freeMemory(); + long memoryUsed = (memoryNow - initialMemory) / 1024L; + long timeUsed = System.currentTimeMillis() - startTime; + if (getLogger().isDebugEnabled()) { + getLogger().debug("Initial heap size: " + (initialMemory / 1024L) + "Kb"); + getLogger().debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); + getLogger().debug("Total memory used: " + memoryUsed + "Kb"); + if (!MEM_PROFILE_WITH_GC) { + getLogger().debug(" Memory use is indicative; no GC was performed"); + getLogger().debug(" These figures should not be used comparatively"); + } + getLogger().debug("Total time used: " + timeUsed + "ms"); + getLogger().debug("Pages rendered: " + pageCount); + if (pageCount > 0) { + getLogger().debug("Avg render time: " + (timeUsed / pageCount) + "ms/page"); + } + } + } + } + + /** + * Start a page sequence. + * At the start of a page sequence it can start the page sequence + * on the area tree with the page sequence title. + * + * @param pageSeq the page sequence starting + * @param seqTitle the title of the page sequence + * @param lms the layout master set + */ + public void startPageSequence(PageSequence pageSeq, + org.apache.fop.fo.Title seqTitle, + LayoutMasterSet lms) { + Title title = null; + if (seqTitle != null) { + title = seqTitle.getTitleArea(); + } + areaTree.startPageSequence(title); + } + + /** + * End the PageSequence. + * The PageSequence formats Pages and adds them to the AreaTree. + * The area tree then handles what happens with the pages. + * + * @param pageSequence the page sequence ending + * @throws FOPException if there is an error formatting the pages + */ + public void endPageSequence(PageSequence pageSequence) + throws FOPException { + //areaTree.setFontInfo(fontInfo); + + if (collectStatistics) { + if (MEM_PROFILE_WITH_GC) { + // This takes time but gives better results + System.gc(); + } + long memoryNow = runtime.totalMemory() - runtime.freeMemory(); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); + } + } + pageSequence.format(areaTree); + } + + /** + * Process an area tree. + * If a store pages model is used this can read and send all the + * pages to the renderer. + * + * @param model the store pages model + * @throws FOPException if there is an error + */ + private void processAreaTree(StorePagesModel model) throws FOPException { + int count = 0; + int seqc = model.getPageSequenceCount(); + while (count < seqc) { + Title title = model.getTitle(count); + renderer.startPageSequence(title); + int pagec = model.getPageCount(count); + for (int c = 0; c < pagec; c++) { + try { + renderer.renderPage(model.getPage(count, c)); + } catch (IOException ioex) { + throw new FOPException("I/O Error rendering page", + ioex); + } + } + count++; + } + List list = model.getEndExtensions(); + for (count = 0; count < list.size(); count++) { + TreeExt ext = (TreeExt)list.get(count); + renderer.renderExtension(ext); + } + } + + /** + * Get the font information for the layout handler. + * + * @return the font information + */ + public FontInfo getFontInfo() { + return this.fontInfo; + } +} + diff --git a/src/java/org/apache/fop/apps/PrintStarter.java b/src/java/org/apache/fop/apps/PrintStarter.java new file mode 100644 index 000000000..f1c3660cd --- /dev/null +++ b/src/java/org/apache/fop/apps/PrintStarter.java @@ -0,0 +1,239 @@ +/* + * $Id: PrintStarter.java,v 1.14 2003/02/27 10:13:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +/* + * originally contributed by + * Stanislav Gorkhover: stanislav.gorkhover@jcatalog.com + * jCatalog Software AG + * + * Updated by Mark Lillywhite, mark-fop@inomial.com. Modified to + * handle the print job better, added -Ddialog option, removed + * (apparently) redundant copies code, generally cleaned up, and + * added interfaces to the new Render API. + */ + + +import org.xml.sax.XMLReader; + +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.io.OutputStream; +import java.io.IOException; +import java.util.Vector; + +import org.apache.fop.render.awt.AWTRenderer; + +/** + * This class prints a XSL-FO dokument without interaction. + * At the moment java has not the possibility to configure the printer and it's + * options without interaction (30.03.2000). + * This class allows to print a set of pages (from-to), even/odd pages and many copies. + * - Print from page xxx: property name - start, value int + * - Print to page xxx: property name - end, value int + * - Print even/odd pages: property name - even, value boolean + * - Print xxx copies: property name - copies, value int + */ +public class PrintStarter extends CommandLineStarter { + + /** + * @see org.apache.fop.apps.CommandLineStarter#CommandLineStarter(CommandLineOptions) + */ + public PrintStarter(CommandLineOptions options) throws FOPException { + super(options); + } + + /** + * @see org.apache.fop.apps.Starter#run() + */ + public void run() throws FOPException { + Driver driver = new Driver(); + + String version = Version.getVersion(); + //log.debug(version); + + XMLReader parser = inputHandler.getParser(); + + setParserFeatures(parser); + + PrinterJob pj = PrinterJob.getPrinterJob(); + if (System.getProperty("dialog") != null) { + if (!pj.printDialog()) { + throw new FOPException("Printing cancelled by operator"); + } + } + + PrintRenderer renderer = new PrintRenderer(pj); + int copies = getIntProperty("copies", 1); + pj.setCopies(copies); + + //renderer.setCopies(copies); + + try { + driver.setRenderer(renderer); + driver.render(parser, inputHandler.getInputSource()); + } catch (Exception e) { + if (e instanceof FOPException) { + throw (FOPException)e; + } + throw new FOPException(e); + } + + System.exit(0); + } + int getIntProperty(String name, int def) { + String propValue = System.getProperty(name); + if (propValue != null) { + try { + return Integer.parseInt(propValue); + } catch (Exception e) { + return def; + } + } else { + return def; + } + } + + class PrintRenderer extends AWTRenderer { + + private static final int EVEN_AND_ALL = 0; + private static final int EVEN = 1; + private static final int ODD = 2; + + private int startNumber; + private int endNumber; + private int mode = EVEN_AND_ALL; + private int copies = 1; + private PrinterJob printerJob; + + PrintRenderer(PrinterJob printerJob) { + super(null); + + this.printerJob = printerJob; + startNumber = getIntProperty("start", 1) - 1; + endNumber = getIntProperty("end", -1); + + printerJob.setPageable(this); + + mode = EVEN_AND_ALL; + String str = System.getProperty("even"); + if (str != null) { + mode = Boolean.valueOf(str).booleanValue() ? EVEN : ODD; + } + + } + + public void stopRenderer(OutputStream outputStream) + throws IOException { + super.stopRenderer(); + + if (endNumber == -1) { + endNumber = getPageCount(); + } + + Vector numbers = getInvalidPageNumbers(); + for (int i = numbers.size() - 1; i > -1; i--) { + //removePage(Integer.parseInt((String)numbers.elementAt(i))); + } + + try { + printerJob.print(); + } catch (PrinterException e) { + e.printStackTrace(); + throw new IOException("Unable to print: " + + e.getClass().getName() + + ": " + e.getMessage()); + } + } + + /*public void renderPage(Page page) { + pageWidth = (int)((float)page.getWidth() / 1000f); + pageHeight = (int)((float)page.getHeight() / 1000f); + }*/ + + private Vector getInvalidPageNumbers() { + + Vector vec = new Vector(); + int max = getPageCount(); + boolean isValid; + for (int i = 0; i < max; i++) { + isValid = true; + if (i < startNumber || i > endNumber) { + isValid = false; + } else if (mode != EVEN_AND_ALL) { + if (mode == EVEN && ((i + 1) % 2 != 0)) { + isValid = false; + } else if (mode == ODD && ((i + 1) % 2 != 1)) { + isValid = false; + } + } + + if (!isValid) { + vec.add(i + ""); + } + } + + return vec; + } + + /* TODO: I'm totally not sure that this is necessary -Mark + void setCopies(int val) { + copies = val; + Vector copie = tree.getPages(); + for (int i = 1; i < copies; i++) { + tree.getPages().addAll(copie); + } + + } + */ + } // class PrintRenderer +} // class PrintCommandLine + diff --git a/src/java/org/apache/fop/apps/Starter.java b/src/java/org/apache/fop/apps/Starter.java new file mode 100644 index 000000000..f4b5d2ee8 --- /dev/null +++ b/src/java/org/apache/fop/apps/Starter.java @@ -0,0 +1,107 @@ +/* + * $Id: Starter.java,v 1.12 2003/02/27 10:13:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; + +// SAX +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; + +/** + * Abstract super class. + * Creates a SAX Parser (defaulting to Xerces). + */ +public abstract class Starter extends AbstractLogEnabled { + + /** InputHandler associated with this Starter */ + protected InputHandler inputHandler; + + /** + * Main constructor + * @throws FOPException In case of a problem constructing the Starter + */ + public Starter() throws FOPException { + } + + /** + * Sets the InputHandler to use. + * @param inputHandler input handler + */ + public void setInputHandler(InputHandler inputHandler) { + this.inputHandler = inputHandler; + } + + /** + * Runs the current setup. + * @throws FOPException In case of a problem during the FOP run + */ + public abstract void run() throws FOPException; + + /** + * Sets the parser features on an XMLReader + * @param parser XMLReader to set features on + * @throws FOPException if the XMLReader doesn't support the feature that + * need to be set + */ + public void setParserFeatures(XMLReader parser) throws FOPException { + try { + parser.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + } catch (SAXException e) { + throw new FOPException("Error: You need a parser which allows the" + + " http://xml.org/sax/features/namespace-prefixes" + + " feature to be set to true to support namespaces", e); + } + } + +} diff --git a/src/java/org/apache/fop/apps/StructureHandler.java b/src/java/org/apache/fop/apps/StructureHandler.java new file mode 100644 index 000000000..d63833acd --- /dev/null +++ b/src/java/org/apache/fop/apps/StructureHandler.java @@ -0,0 +1,295 @@ +/* + * $Id: StructureHandler.java,v 1.7 2003/02/27 10:13:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Java +import java.util.Set; +import java.util.HashSet; + +// Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; + +// FOP +import org.apache.fop.fo.Title; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Flow; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.Leader; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.Table; +import org.apache.fop.fo.flow.TableBody; +import org.apache.fop.fo.flow.TableCell; +import org.apache.fop.fo.flow.TableRow; +import org.apache.fop.fo.pagination.LayoutMasterSet; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.layout.FontInfo; + +import org.xml.sax.SAXException; + +/** + * This class receives structure events from the FO Tree. + * Sub-classes can then implement various methods to handle + * the FO Tree when the SAX events occur. + */ +public class StructureHandler extends AbstractLogEnabled { + /** + * The current set of id's in the FO tree. + * This is used so we know if the FO tree contains duplicates. + */ + private Set idReferences = new HashSet(); + + /** + * Main constructor + */ + public StructureHandler() { + } + + /** + * Retuns the set of ID references. + * @return the ID references + */ + public Set getIDReferences() { + return idReferences; + } + + /** + * Returns the FontInfo object associated with this StructureHandler. + * @return the FontInof object + */ + public FontInfo getFontInfo() { + return null; + } + + /** + * This method is called to indicate the start of a new document run. + * @throws SAXException In case of a problem + */ + public void startDocument() throws SAXException { + } + + /** + * This method is called to indicate the end of a document run. + * @throws SAXException In case of a problem + */ + public void endDocument() throws SAXException { + } + + public void startPageSequence(PageSequence pageSeq, Title seqTitle, LayoutMasterSet lms) { + + } + + public void endPageSequence(PageSequence pageSeq) throws FOPException { + + } + + public void startFlow(Flow fl) { + + } + + public void endFlow(Flow fl) { + + } + + public void startBlock(Block bl) { + + } + + public void endBlock(Block bl) { + + } + + + // Tables + public void startTable(Table tbl) { + + } + + public void endTable(Table tbl) { + + } + + public void startHeader(TableBody th) { + + } + + public void endHeader(TableBody th) { + + } + + public void startFooter(TableBody tf) { + + } + + public void endFooter(TableBody tf) { + + } + + public void startBody(TableBody tb) { + + } + + public void endBody(TableBody tb) { + + } + + public void startRow(TableRow tr) { + + } + + public void endRow(TableRow tr) { + + } + + public void startCell(TableCell tc) { + + } + + public void endCell(TableCell tc) { + + } + + + // Lists + public void startList(ListBlock lb) { + + } + + public void endList(ListBlock lb) { + + } + + public void startListItem(ListItem li) { + + } + + public void endListItem(ListItem li) { + + } + + public void startListLabel() { + + } + + public void endListLabel() { + + } + + public void startListBody() { + + } + + public void endListBody() { + + } + + + // Static Regions + public void startStatic() { + + } + + public void endStatic() { + + } + + + public void startMarkup() { + + } + + public void endMarkup() { + + } + + + public void startLink() { + + } + + public void endLink() { + + } + + + public void image(ExternalGraphic eg) { + + } + + public void pageRef() { + + } + + public void foreignObject(InstreamForeignObject ifo) { + + } + + public void footnote() { + + } + + public void leader(Leader l) { + + } + + + public void characters(char data[], int start, int length) { + + } + + public void pageBreak() { + + } + + +} + diff --git a/src/java/org/apache/fop/apps/TraxInputHandler.java b/src/java/org/apache/fop/apps/TraxInputHandler.java new file mode 100644 index 000000000..cc488a898 --- /dev/null +++ b/src/java/org/apache/fop/apps/TraxInputHandler.java @@ -0,0 +1,152 @@ +/* + * $Id: TraxInputHandler.java,v 1.6 2003/02/27 10:13:04 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Imported java.io classes +import java.io.File; + +// Imported TraX classes +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; + +// Imported SAX classes +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; +import org.xml.sax.XMLFilter; + +/** + * XSLTInputHandler basically takes an XML file and transforms it with an + * XSLT file and the resulting XSL-FO document is input for FOP. + */ +public class TraxInputHandler extends InputHandler { + + private File xmlfile, xsltfile; + + /** + * Main constructor + * @param xmlfile XML file + * @param xsltfile XSLT file + */ + public TraxInputHandler(File xmlfile, File xsltfile) { + this.xmlfile = xmlfile; + this.xsltfile = xsltfile; + } + + /** + * @see org.apache.fop.apps.InputHandler#getInputSource() + */ + public InputSource getInputSource() { + return fileInputSource(xmlfile); + } + + /** + * Overwrites this method of the super class and returns an XMLFilter + * instead of a simple XMLReader which allows chaining of transformations. + * @see org.apache.fop.apps.InputHandler#getParser() + */ + public XMLReader getParser() throws FOPException { + return this.getXMLFilter(xmlfile, xsltfile); + } + + /** + * Creates from the transformer an instance of an XMLFilter which + * then can be used in a chain with the XMLReader passed to Driver. This way + * during the conversion of the xml file + xslt stylesheet the resulting + * data is fed into Fop. This should help to avoid memory problems + * @param xmlfile The xmlfile containing the text data + * @param xsltfile An xslt stylesheet + * @return an XMLFilter which can be chained together with other + * XMLReaders or XMLFilters + * @throws FOPException if setting up the XMLFilter fails + */ + public static XMLFilter getXMLFilter(File xmlfile, + File xsltfile) throws FOPException { + try { + // Instantiate a TransformerFactory. + TransformerFactory tFactory = TransformerFactory.newInstance(); + // Determine whether the TransformerFactory supports The use uf SAXSource + // and SAXResult + if (tFactory.getFeature(SAXSource.FEATURE) + && tFactory.getFeature(SAXResult.FEATURE)) { + // Cast the TransformerFactory to SAXTransformerFactory. + SAXTransformerFactory saxTFactory = + ((SAXTransformerFactory)tFactory); + // Create an XMLFilter for each stylesheet. + XMLFilter xmlfilter = + saxTFactory.newXMLFilter(new StreamSource(xsltfile)); + + // Create an XMLReader. + XMLReader parser = createParser(); + if (parser == null) { + throw new FOPException("Unable to create SAX parser"); + } + + // xmlFilter1 uses the XMLReader as its reader. + xmlfilter.setParent(parser); + return xmlfilter; + } else { + throw new FOPException("Your parser doesn't support the " + + "features SAXSource and SAXResult." + + "\nMake sure you are using an XSLT engine which " + + "supports TrAX"); + } + } catch (FOPException fe) { + throw fe; + } catch (Exception ex) { + throw new FOPException(ex); + } + } + +} + diff --git a/src/java/org/apache/fop/apps/Version.java b/src/java/org/apache/fop/apps/Version.java new file mode 100644 index 000000000..e1bfc1e19 --- /dev/null +++ b/src/java/org/apache/fop/apps/Version.java @@ -0,0 +1,67 @@ +/* + * $Id: Version.java,v 1.18 2003/02/27 10:13:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +/** + * Class representing the version of FOP. + */ +public class Version { + + /** + * Get the version of FOP + * + * @return the version string + */ + public static String getVersion() { + return "1.0dev"; + } + +} diff --git a/src/java/org/apache/fop/apps/XSLTInputHandler.java b/src/java/org/apache/fop/apps/XSLTInputHandler.java new file mode 100644 index 000000000..dc73ce3ca --- /dev/null +++ b/src/java/org/apache/fop/apps/XSLTInputHandler.java @@ -0,0 +1,182 @@ +/* + * $Id: XSLTInputHandler.java,v 1.10 2003/02/27 10:13:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.apps; + +// Imported java.io classes +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +// Imported SAX classes +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +// FOP +import org.apache.fop.tools.xslt.XSLTransform; + +/** + * XSLTInputHandler basically takes an XML file and transforms it with an XSLT + * file and the resulting XSL-FO document is input for FOP. + * @todo add URL constructor + */ +public class XSLTInputHandler extends InputHandler { + + private File xmlfile, xsltfile; + private boolean useOldTransform = false; + private boolean gotParser = false; + + /** + * Main constructor + * @param xmlfile XML file + * @param xsltfile XSLT file + */ + public XSLTInputHandler(File xmlfile, File xsltfile) { + this.xmlfile = xmlfile; + this.xsltfile = xsltfile; + } + + /** + * @see org.apache.fop.apps.InputHandler#getInputSource() + */ + public InputSource getInputSource() { + if (!gotParser) { + throw new IllegalStateException("The method getParser() must be " + + "called and the parser used when using XSLTInputHandler"); + } + if (useOldTransform) { + try { + java.io.Writer writer; + java.io.Reader reader; + File tmpFile = null; + + // create a Writer + // the following is an ugly hack to allow processing of larger files + // if xml file size is larger than 500 kb write the fo:file to disk + if ((xmlfile.length()) > 500000) { + tmpFile = new File(xmlfile.getName() + ".fo.tmp"); + writer = new java.io.FileWriter(tmpFile); + } else { + writer = new java.io.StringWriter(); + } + + XSLTransform.transform(xmlfile.getCanonicalPath(), + xsltfile.getCanonicalPath(), writer); + + writer.flush(); + writer.close(); + + if (tmpFile != null) { + reader = new java.io.FileReader(tmpFile); + } else { + // create a input source containing the xsl:fo file which can be fed to Fop + reader = new java.io.StringReader(writer.toString()); + } + return new InputSource(reader); + } catch (Exception ex) { + ex.printStackTrace(); + /**@todo do proper logging of exceptions */ + return null; + } + } else { + return fileInputSource(xmlfile); + } + + } + + /** + * This looks to see if the Trax api is supported and uses that to + * get an XMLFilter. Otherwise, it falls back to using DOM documents + * @return the created XMLReader + * @throws FOPException if getting the parser fails + * @see org.apache.fop.apps.InputHandler#getParser() + */ + public XMLReader getParser() throws FOPException { + gotParser = true; + + XMLReader result = null; + try { + // try trax first + Class transformer = + Class.forName("javax.xml.transform.Transformer"); + transformer = + Class.forName("org.apache.fop.apps.TraxInputHandler"); + Class[] argTypes = { + File.class, File.class + }; + Method getFilterMethod = transformer.getMethod("getXMLFilter", + argTypes); + File[] args = { + xmlfile, xsltfile + }; + Object obj = getFilterMethod.invoke(null, args); + if (obj instanceof XMLReader) { + result = (XMLReader)obj; + } + } catch (ClassNotFoundException ex) { + throw new FOPException(ex); + } catch (InvocationTargetException ex) { + throw new FOPException(ex); + } catch (IllegalAccessException ex) { + throw new FOPException(ex); + } catch (NoSuchMethodException ex) { + throw new FOPException(ex); + } + // otherwise, use DOM documents via our XSLTransform tool class old style + if (result == null) { + useOldTransform = true; + result = createParser(); + } + return result; + + } + +} + diff --git a/src/java/org/apache/fop/apps/package.html b/src/java/org/apache/fop/apps/package.html new file mode 100644 index 000000000..c8a9798d5 --- /dev/null +++ b/src/java/org/apache/fop/apps/package.html @@ -0,0 +1,7 @@ + +org.apache.fop.apps Package + +

Application classes used for running FOP both on the command line and +embedded in other applications.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java new file mode 100644 index 000000000..fec8cbb79 --- /dev/null +++ b/src/java/org/apache/fop/area/Area.java @@ -0,0 +1,265 @@ +/* + * $Id: Area.java,v 1.16 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.io.Serializable; + +import java.util.Map; +import java.util.HashMap; + +// If the area appears more than once in the output +// or if the area has external data it is cached +// to keep track of it and to minimize rendered output +// renderers can render the output once and display it +// for every occurence +// this should also extend to all outputs (including PDFGraphics2D) +// and all types of renderers + +/** + * Base object for all areas. + */ +public class Area implements Serializable { + // stacking directions + /** + * Stacking left to right + */ + public static final int LR = 0; + + /** + * Stacking right to left + */ + public static final int RL = 1; + + /** + * Stacking top to bottom + */ + public static final int TB = 2; + + /** + * Stacking bottom to top + */ + public static final int BT = 3; + + // orientations for reference areas + /** + * Normal orientation + */ + public static final int ORIENT_0 = 0; + + /** + * Rotated 90 degrees clockwise + */ + public static final int ORIENT_90 = 1; + + /** + * Rotate 180 degrees + */ + public static final int ORIENT_180 = 2; + + /** + * Rotated 270 degrees clockwise + */ + public static final int ORIENT_270 = 3; + + // area class values + + /** + * Normal class + */ + public static final int CLASS_NORMAL = 0; + + /** + * Fixed position class + */ + public static final int CLASS_FIXED = 1; + + /** + * Absolute position class + */ + public static final int CLASS_ABSOLUTE = 2; + + /** + * Before float class + */ + public static final int CLASS_BEFORE_FLOAT = 3; + + /** + * Footnote class + */ + public static final int CLASS_FOOTNOTE = 4; + + /** + * Side float class + */ + public static final int CLASS_SIDE_FLOAT = 5; + + // IMPORTANT: make sure this is the maximum + 1 + /** + * Maximum class count + */ + public static final int CLASS_MAX = CLASS_SIDE_FLOAT + 1; + + private int areaClass = CLASS_NORMAL; + private int ipd; + + /** + * Traits for this area stored in a HashMap + */ + protected HashMap props = null; + + /** + * Get the area class of this area. + * + * @return the area class + */ + public int getAreaClass() { + return areaClass; + } + + /** + * Set the area class of this area. + * + * @param areaClass the area class + */ + public void setAreaClass(int areaClass) { + this.areaClass = areaClass; + } + + /** + * Set the inline progression dimension of this area. + * + * @param i the new inline progression dimension + */ + public void setIPD(int i) { + ipd = i; + } + + /** + * Get the inline progression dimension of this area. + * + * @return the inline progression dimension + */ + public int getIPD() { + return ipd; + } + + /** + * Add a child to this area. + * The default is to do nothing. Subclasses must override + * to do something if they can have child areas. + * + * @param child the child area to add + */ + public void addChild(Area child) { + } + + /** + * Add a trait property to this area. + * + * @param prop the Trait to add + */ + public void addTrait(Trait prop) { + if (props == null) { + props = new java.util.HashMap(20); + } + props.put(prop.getPropType(), prop.getData()); + } + + /** + * Add a trait to this area. + * + * @param traitCode the trait key + * @param prop the value of the trait + */ + public void addTrait(Object traitCode, Object prop) { + if (props == null) { + props = new java.util.HashMap(20); + } + props.put(traitCode, prop); + } + + /** + * Get the map of all traits on this area. + * + * @return the map of traits + */ + public Map getTraits() { + return this.props; + } + + /** + * Get a trait from this area. + * + * @param oTraitCode the trait key + * @return the trait value + */ + public Object getTrait(Object oTraitCode) { + return (props != null ? props.get(oTraitCode) : null); + } + + /** + * Get a trait from this area as an integer. + * + * @param oTraitCode the trait key + * @return the trait value + */ + public int getTraitAsInteger(Object oTraitCode) { + final Object obj = getTrait(oTraitCode); + if (obj instanceof Integer) { + return ((Integer)obj).intValue(); + } else { + throw new IllegalArgumentException("Trait " + + oTraitCode.getClass().getName() + + " could not be converted to an integer"); + } + } +} + diff --git a/src/java/org/apache/fop/area/AreaTree.java b/src/java/org/apache/fop/area/AreaTree.java new file mode 100644 index 000000000..8c499c733 --- /dev/null +++ b/src/java/org/apache/fop/area/AreaTree.java @@ -0,0 +1,248 @@ +/* + * $Id: AreaTree.java,v 1.16 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import org.apache.fop.render.Renderer; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; + +/** + * Area tree for formatting objects. + * + * Concepts: + * The area tree is to be as small as possible. With minimal classes + * and data to fully represent an area tree for formatting objects. + * The area tree needs to be simple to render and follow the spec + * closely. + * This area tree has the concept of page sequences. + * Where ever possible information is discarded or optimised to + * keep memory use low. The data is also organised to make it + * possible for renderers to minimise their output. + * A page can be saved if not fully resolved and once rendered + * a page contains only size and id reference information. + * The area tree pages are organised in a model that depends on the + * type of renderer. + */ +public class AreaTree { + // allows for different models to deal with adding/rendering + // in different situations + private AreaTreeModel model; + + // hashmap of arraylists containing pages with id area + private Map idLocations = new HashMap(); + // list of id's yet to be resolved and arraylists of pages + private Map resolve = new HashMap(); + private List treeExtensions = new ArrayList(); + + /** + * Create a render pages area tree model. + * @param rend the renderer that will be used + * @return RenderPagesModel the new area tree model + */ + public static RenderPagesModel createRenderPagesModel(Renderer rend) { + return new RenderPagesModel(rend); + } + + /** + * Create a new store pages model. + * @return StorePagesModel the new model + */ + public static StorePagesModel createStorePagesModel() { + return new StorePagesModel(); + } + + /** + * Set the tree model to use for this area tree. + * The different models can have different behaviour + * when pages area added and other changes. + * @param m the area tree model + */ + public void setTreeModel(AreaTreeModel m) { + model = m; + } + + /** + * Get the area tree model for this area tree. + * + * @return AreaTreeModel the model being used for this area tree + */ + public AreaTreeModel getAreaTreeModel() { + return model; + } + + /** + * Start a new page sequence. + * This signals that a new page sequence has started in the document. + * @param title the title of the new page sequence or null if no title + */ + public void startPageSequence(Title title) { + model.startPageSequence(title); + } + + /** + * Add a new page to the area tree. + * @param page the page to add + */ + public void addPage(PageViewport page) { + model.addPage(page); + } + + /** + * Add an id reference pointing to a page viewport. + * @param id the id of the reference + * @param pv the page viewport that contains the id reference + */ + public void addIDRef(String id, PageViewport pv) { + List list = (List)idLocations.get(id); + if (list == null) { + list = new ArrayList(); + idLocations.put(id, list); + } + list.add(pv); + + Set todo = (Set)resolve.get(id); + if (todo != null) { + for (Iterator iter = todo.iterator(); iter.hasNext();) { + Resolveable res = (Resolveable)iter.next(); + res.resolve(id, list); + } + resolve.remove(id); + } + } + + /** + * Get the list of id references for an id. + * @param id the id to lookup + * @return the list of id references. + */ + public List getIDReferences(String id) { + return (List)idLocations.get(id); + } + + /** + * Add an unresolved object with a given id. + * @param id the id reference that needs resolving + * @param res the Resolveable object to resolve + */ + public void addUnresolvedID(String id, Resolveable res) { + Set todo = (Set)resolve.get(id); + if (todo == null) { + todo = new HashSet(); + resolve.put(id, todo); + } + todo.add(res); + } + + /** + * Add a tree extension. + * This checks if the extension is resolveable and attempts + * to resolve or add the resolveable ids for later resolution. + * @param ext the tree extension to add. + */ + public void addTreeExtension(TreeExt ext) { + treeExtensions.add(ext); + if (ext.isResolveable()) { + Resolveable res = (Resolveable)ext; + String[] ids = res.getIDs(); + for (int count = 0; count < ids.length; count++) { + if (idLocations.containsKey(ids[count])) { + res.resolve(ids[count], (List)idLocations.get(ids[count])); + } else { + Set todo = (Set)resolve.get(ids[count]); + if (todo == null) { + todo = new HashSet(); + resolve.put(ids[count], todo); + } + todo.add(ext); + } + } + } else { + handleTreeExtension(ext, TreeExt.IMMEDIATELY); + } + } + + /** + * Handle a tree extension. + * This sends the extension to the model for handling. + * @param ext the tree extension to handle + * @param when when the extension should be handled by the model + */ + public void handleTreeExtension(TreeExt ext, int when) { + // queue tree extension according to the when + model.addExtension(ext, when); + } + + /** + * Signal end of document. + * This indicates that the document is complete and any unresolved + * reference can be dealt with. + */ + public void endDocument() { + for (Iterator iter = resolve.keySet().iterator(); iter.hasNext();) { + String id = (String)iter.next(); + Set list = (Set)resolve.get(id); + for (Iterator resIter = list.iterator(); resIter.hasNext();) { + Resolveable res = (Resolveable)resIter.next(); + if (!res.isResolved()) { + res.resolve(id, null); + } + } + } + model.endDocument(); + } +} + diff --git a/src/java/org/apache/fop/area/AreaTreeModel.java b/src/java/org/apache/fop/area/AreaTreeModel.java new file mode 100644 index 000000000..5f44b6c1c --- /dev/null +++ b/src/java/org/apache/fop/area/AreaTreeModel.java @@ -0,0 +1,114 @@ +/* + * $Id: AreaTreeModel.java,v 1.4 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * This is the model for the area tree object. + * The model implementation can handle the page sequence, + * page and extensions. + * The mathods to acces the page viewports can only + * assume the PageViewport is valid as it remains for + * the life of the area tree model. + */ +public abstract class AreaTreeModel { + /** + * Start a page sequence on this model. + * @param title the title of the new page sequence + */ + public abstract void startPageSequence(Title title); + + /** + * Add a page to this moel. + * @param page the page to add to the model. + */ + public abstract void addPage(PageViewport page); + + /** + * Add an extension to this model. + * @param ext the extension to add + * @param when when the extension should be handled + */ + public abstract void addExtension(TreeExt ext, int when); + + /** + * Signal the end of the document for any processing. + */ + public abstract void endDocument(); + + /** + * Get the page sequence count. + * @return the number of page sequences in the document. + */ + public abstract int getPageSequenceCount(); + + /** + * Get the title for a page sequence. + * @param count the page sequence count + * @return the title of the page sequence + */ + public abstract Title getTitle(int count); + + /** + * Get the page count. + * @param seq the page sequence to count. + * @return returns the number of pages in a page sequence + */ + public abstract int getPageCount(int seq); + + /** + * Get the page for a position in the document. + * @param seq the page sequence number + * @param count the page count in the sequence + * @return the PageViewport for the particular page + */ + public abstract PageViewport getPage(int seq, int count); + +} diff --git a/src/java/org/apache/fop/area/BeforeFloat.java b/src/java/org/apache/fop/area/BeforeFloat.java new file mode 100644 index 000000000..b366bf1e3 --- /dev/null +++ b/src/java/org/apache/fop/area/BeforeFloat.java @@ -0,0 +1,97 @@ +/* + * $Id: BeforeFloat.java,v 1.5 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * The before float area. + * This is used to place the before float areas. + * It has an optional separator and before float block children. + */ +public class BeforeFloat extends BlockParent { + // this is an optional block area that will be rendered + // as the separator only if there are float areas + private Block separator = null; + + /** + * Set the separator area for this before float. + * + * @param sep the before float separator area + */ + public void setSeparator(Block sep) { + separator = sep; + } + + /** + * Get the separator area for this before float. + * + * @return the before float separator area + */ + public Block getSeparator() { + return separator; + } + + /** + * Get the height of this before float. + * It gets the height of the children and if there is a + * separator its height is also added. + * + * @return the height of the before float including separator + */ + public int getHeight() { + int h = super.getHeight(); + if (separator != null) { + h += separator.getHeight(); + } + return h; + } + +} + diff --git a/src/java/org/apache/fop/area/Block.java b/src/java/org/apache/fop/area/Block.java new file mode 100644 index 000000000..2c7273a61 --- /dev/null +++ b/src/java/org/apache/fop/area/Block.java @@ -0,0 +1,135 @@ +/* + * $Id: Block.java,v 1.12 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.ArrayList; + +// block areas hold either more block areas or line +// areas can also be used as a block spacer +// a block area may have children positioned by stacking +// or by relative to the parent for floats, tables and lists +// cacheable object +// has id information + +/** + * This is the block area class. + * It holds child block areas such as other blocks or lines. + */ +public class Block extends BlockParent { + /** + * Normally stacked with other blocks. + */ + public static final int STACK = 0; + + /** + * Placed relative to the flow position. + * This effects the flow placement of stacking normally. + */ + public static final int RELATIVE = 1; + + /** + * Relative to the block parent but not effecting the stacking + * Used for block-container, tables and lists. + */ + public static final int ABSOLUTE = 2; + + private int stacking = TB; + private int positioning = STACK; + + // a block with may contain the dominant styling info in + // terms of most lines or blocks with info + + /** + * Add the block to this block area. + * + * @param block the block area to add + */ + public void addBlock(Block block) { + if (children == null) { + children = new ArrayList(); + } + height += block.getHeight(); + children.add(block); + } + + /** + * Add the line area to this block area. + * + * @param line the line area to add + */ + public void addLineArea(LineArea line) { + if (children == null) { + children = new ArrayList(); + } + height += line.getHeight(); + children.add(line); + } + + /** + * Set the positioning of this area. + * + * @param pos the positioning to use when rendering this area + */ + public void setPositioning(int pos) { + positioning = pos; + } + + /** + * Get the positioning of this area. + * + * @return the positioning to use when rendering this area + */ + public int getPositioning() { + return positioning; + } + +} + diff --git a/src/java/org/apache/fop/area/BlockParent.java b/src/java/org/apache/fop/area/BlockParent.java new file mode 100644 index 000000000..1b45f861e --- /dev/null +++ b/src/java/org/apache/fop/area/BlockParent.java @@ -0,0 +1,188 @@ +/* + * $Id: BlockParent.java,v 1.7 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.ArrayList; +import java.util.List; + +/** + * A BlockParent holds block-level areas. + */ +public class BlockParent extends Area { + + // this position is used for absolute position + // or as an indent + // this has the size in the block progression dimension + + /** + * The x offset position of this block parent. + * Used for relative and absolute positioning. + */ + protected int xOffset = 0; + + /** + * The y offset position of this block parent. + * Used for relative and absolute positioning. + */ + protected int yOffset = 0; + + /** + * The width of this block parent. + */ + protected int width = 0; + + /** + * The height of this block parent. + */ + protected int height = 0; + + /** + * The children of this block parent area. + */ + protected List children = null; + + // orientation if reference area + private int orientation = ORIENT_0; + + /** + * Add the block area to this block parent. + * + * @param block the child block area to add + */ + public void addBlock(Block block) { + if (children == null) { + children = new ArrayList(); + } + children.add(block); + } + + /** + * Get the list of child areas for this block area. + * + * @return the list of child areas + */ + public List getChildAreas() { + return children; + } + + /** + * Set the X offset of this block parent area. + * + * @param off the x offset of the block parent area + */ + public void setXOffset(int off) { + xOffset = off; + } + + /** + * Set the Y offset of this block parent area. + * + * @param off the y offset of the block parent area + */ + public void setYOffset(int off) { + yOffset = off; + } + + /** + * Set the width of this block parent area. + * + * @param w the width of the area + */ + public void setWidth(int w) { + width = w; + } + + /** + * Set the height of this block parent area. + * + * @param h the height of the block parent area + */ + public void setHeight(int h) { + height = h; + } + + /** + * Get the X offset of this block parent area. + * + * @return the x offset of the block parent area + */ + public int getXOffset() { + return xOffset; + } + + /** + * Get the Y offset of this block parent area. + * + * @return the y offset of the block parent area + */ + public int getYOffset() { + return yOffset; + } + + /** + * Get the width of this block parent area. + * + * @return the width of the area + */ + public int getWidth() { + return width; + } + + /** + * Get the height of this block parent area. + * + * @return the height of the block parent area + */ + public int getHeight() { + return height; + } + +} diff --git a/src/java/org/apache/fop/area/BlockViewport.java b/src/java/org/apache/fop/area/BlockViewport.java new file mode 100644 index 000000000..09734a32a --- /dev/null +++ b/src/java/org/apache/fop/area/BlockViewport.java @@ -0,0 +1,110 @@ +/* + * $Id: BlockViewport.java,v 1.3 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * A BlockViewport. + * This is used for block level Viewport/reference pairs. + * The block-container creates this area. + */ +public class BlockViewport extends Block { + // clipping for this viewport + private boolean clip = false; + // transform if rotated or absolute + private CTM viewportCTM; + + /** + * Create a new block viewport area. + */ + public BlockViewport() { + } + + /** + * Set the transform of this viewport. + * If the viewport is rotated or has an absolute positioning + * this transform will do the work. + * + * @param ctm the transformation + */ + public void setCTM(CTM ctm) { + viewportCTM = ctm; + } + + /** + * Get the transform of this block viewport. + * + * @return the transformation of this viewport + * or null if normally stacked without rotation + */ + public CTM getCTM() { + return viewportCTM; + } + + /** + * Set the clipping for this viewport. + * + * @param cl the clipping for the viewport + */ + public void setClip(boolean cl) { + clip = cl; + } + + /** + * Get the clipping for this viewport. + * + * @return the clipping for the viewport + * true if the contents should be clipped for this viewport + */ + public boolean getClip() { + return clip; + } +} + diff --git a/src/java/org/apache/fop/area/BodyRegion.java b/src/java/org/apache/fop/area/BodyRegion.java new file mode 100644 index 000000000..1db0ed114 --- /dev/null +++ b/src/java/org/apache/fop/area/BodyRegion.java @@ -0,0 +1,173 @@ +/* + * $Id: BodyRegion.java,v 1.9 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * The body region area. + * This area contains a main reference area and optionally a + * before float and footnote area. + */ +public class BodyRegion extends RegionReference { + private BeforeFloat beforeFloat; + private MainReference mainReference; + private Footnote footnote; + private int columnGap; + private int columnCount; + + /** Reference inline progression dimension for the body. */ + private int refIPD; + + /** + * Create a new body region area. + * This sets the region reference area class to BODY. + */ + public BodyRegion() { + super(BODY); + } + + /** + * Set the number of columns for blocks when not spanning + * + * @param colCount the number of columns + */ + public void setColumnCount(int colCount) { + this.columnCount = colCount; + } + + /** + * Get the number of columns when not spanning + * + * @return the number of columns + */ + public int getColumnCount() { + return this.columnCount; + } + + /** + * Set the column gap between columns + * The length is in millipoints. + * + * @param colGap the column gap in millipoints + */ + public void setColumnGap(int colGap) { + this.columnGap = colGap; + } + + /** + * Set the before float area. + * + * @param bf the before float area + */ + public void setBeforeFloat(BeforeFloat bf) { + beforeFloat = bf; + } + + /** + * Set the main reference area. + * + * @param mr the main reference area + */ + public void setMainReference(MainReference mr) { + mainReference = mr; + } + + /** + * Set the footnote area. + * + * @param foot the footnote area + */ + public void setFootnote(Footnote foot) { + footnote = foot; + } + + /** + * Get the before float area. + * + * @return the before float area + */ + public BeforeFloat getBeforeFloat() { + return beforeFloat; + } + + /** + * Get the main reference area. + * + * @return the main reference area + */ + public MainReference getMainReference() { + return mainReference; + } + + /** + * Get the footnote area. + * + * @return the footnote area + */ + public Footnote getFootnote() { + return footnote; + } + + /** + * Clone this object. + * This is only used to clone the current object, the child areas + * are assumed to be null and are not cloned. + * + * @return a shallow copy of this object + */ + public Object clone() { + BodyRegion br = new BodyRegion(); + br.setCTM(getCTM()); + br.setIPD(getIPD()); + br.columnGap = columnGap; + br.columnCount = columnCount; + return br; + } +} diff --git a/src/java/org/apache/fop/area/CTM.java b/src/java/org/apache/fop/area/CTM.java new file mode 100644 index 000000000..9bf8b68f7 --- /dev/null +++ b/src/java/org/apache/fop/area/CTM.java @@ -0,0 +1,282 @@ +/* + * $Id: CTM.java,v 1.8 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.awt.geom.Rectangle2D; +import java.awt.Rectangle; +import java.io.Serializable; + +import org.apache.fop.fo.properties.WritingMode; + +/** + * Describe a PDF or PostScript style coordinate transformation matrix (CTM). + * The matrix encodes translations, scaling and rotations of the coordinate + * system used to render pages. + */ +public class CTM implements Serializable { + + private double a, b, c, d, e, f; + + private static final CTM CTM_LRTB = new CTM(1, 0, 0, 1, 0, 0); + private static final CTM CTM_RLTB = new CTM(-1, 0, 0, 1, 0, 0); + private static final CTM CTM_TBRL = new CTM(0, 1, -1, 0, 0, 0); + + /** + * Create the identity matrix + */ + public CTM() { + a = 1; + b = 0; + c = 0; + d = 1; + e = 0; + f = 0; + } + + /** + * Initialize a CTM from the passed arguments. + * + * @param a the x scale + * @param b the x shear + * @param c the y shear + * @param d the y scale + * @param e the x shift + * @param f the y shift + */ + public CTM(double a, double b, double c, double d, double e, double f) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.e = e; + this.f = f; + } + + /** + * Initialize a CTM to the identity matrix with a translation + * specified by x and y + * + * @param x the x shift + * @param y the y shift. + */ + public CTM(double x, double y) { + this.a = 1; + this.b = 0; + this.c = 0; + this.d = 1; + this.e = x; + this.f = y; + } + + /** + * Initialize a CTM with the values of another CTM. + * + * @param ctm another CTM + */ + protected CTM(CTM ctm) { + this.a = ctm.a; + this.b = ctm.b; + this.c = ctm.c; + this.d = ctm.d; + this.e = ctm.e; + this.f = ctm.f; + } + + /** + * Return a CTM which will transform coordinates for a particular writing-mode + * into normalized first quandrant coordinates. + * @param wm A writing mode constant from fo.properties.WritingMode, ie. + * one of LR_TB, RL_TB, TB_RL. + * @param ipd The inline-progression dimension of the reference area whose + * CTM is being set.. + * @param bpd The block-progression dimension of the reference area whose + * CTM is being set. + * @return a new CTM with the required transform + */ + public static CTM getWMctm(int wm, int ipd, int bpd) { + CTM wmctm; + switch (wm) { + case WritingMode.LR_TB: + return new CTM(CTM_LRTB); + case WritingMode.RL_TB: + { + wmctm = new CTM(CTM_RLTB); + wmctm.e = ipd; + return wmctm; + } + //return CTM_RLTB.translate(ipd, 0); + case WritingMode.TB_RL: // CJK + { + wmctm = new CTM(CTM_TBRL); + wmctm.e = bpd; + return wmctm; + } + //return CTM_TBRL.translate(0, ipd); + default: + return null; + } + } + + /** + * Multiply new passed CTM with this one and generate a new result CTM. + * @param premult The CTM to multiply with this one. The new one will be + * the first multiplicand. + * @return CTM The result of multiplying premult * this. + */ + public CTM multiply(CTM premult) { + CTM rslt = new CTM ((premult.a * a) + (premult.b * c), + (premult.a * b) + (premult.b * d), + (premult.c * a) + (premult.d * c), + (premult.c * b) + (premult.d * d), + (premult.e * a) + (premult.f * c) + e, + (premult.e * b) + (premult.f * d) + f); + return rslt; + } + + /** + * Rotate this CTM by "angle" radians and return a new result CTM. + * This is used to account for reference-orientation. + * @param angle The angle in radians. Positive angles are measured counter- + * clockwise. + * @return CTM The result of rotating this CTM. + */ + public CTM rotate(double angle) { + double cos, sin; + if (angle == 90.0) { + cos = 0.0; + sin = 1.0; + } else if (angle == 270.0) { + cos = 0.0; + sin = -1.0; + } else if (angle == 180.0) { + cos = -1.0; + sin = 0.0; + } else { + double rad = Math.toRadians(angle); + cos = Math.cos(rad); + sin = Math.sin(rad); + } + CTM rotate = new CTM(cos, -sin, sin, cos, 0, 0); + return multiply(rotate); + } + + /** + * Translate this CTM by the passed x and y values and return a new result CTM. + * @param x The amount to translate along the x axis. + * @param y The amount to translate along the y axis. + * @return CTM The result of translating this CTM. + */ + public CTM translate(double x, double y) { + CTM translate = new CTM(1, 0, 0, 1, x, y); + return multiply(translate); + } + + /** + * Scale this CTM by the passed x and y values and return a new result CTM. + * @param x The amount to scale along the x axis. + * @param y The amount to scale along the y axis. + * @return CTM The result of scaling this CTM. + */ + public CTM scale(double x, double y) { + CTM scale = new CTM(x, 0, 0, y, 0, 0); + return multiply(scale); + } + + /** + * Transform a rectangle by the CTM to produce a rectangle in the transformed + * coordinate system. + * @param inRect The rectangle in the original coordinate system + * @return Rectangle2D The rectangle in the transformed coordinate system. + */ + public Rectangle2D transform(Rectangle2D inRect) { + // Store as 2 sets of 2 points and transform those, then + // recalculate the width and height + int x1t = (int)(inRect.getX() * a + inRect.getY() * c + e); + int y1t = (int)(inRect.getX() * b + inRect.getY() * d + f); + int x2t = (int)((inRect.getX() + inRect.getWidth()) * a + + (inRect.getY() + inRect.getHeight()) * c + e); + int y2t = (int)((inRect.getX() + inRect.getWidth()) * b + + (inRect.getY() + inRect.getHeight()) * d + f); + // Normalize with x1 < x2 + if (x1t > x2t) { + int tmp = x2t; + x2t = x1t; + x1t = tmp; + } + if (y1t > y2t) { + int tmp = y2t; + y2t = y1t; + y1t = tmp; + } + return new Rectangle(x1t, y1t, x2t - x1t, y2t - y1t); + } + + /** + * Get string for this transform. + * + * @return a string with the transform values + */ + public String toString() { + return "[" + a + " " + b + " " + c + " " + d + " " + e + " " + + f + "]"; + } + + /** + * Get an array containing the values of this transform. + * This creates and returns a new transform with the values in it. + * + * @return an array containing the transform values + */ + public double[] toArray() { + return new double[]{a, b, c, d, e, f}; + } +} + diff --git a/src/java/org/apache/fop/area/CachedRenderPagesModel.java b/src/java/org/apache/fop/area/CachedRenderPagesModel.java new file mode 100644 index 000000000..e20582854 --- /dev/null +++ b/src/java/org/apache/fop/area/CachedRenderPagesModel.java @@ -0,0 +1,157 @@ +/* + * $Id: CachedRenderPagesModel.java,v 1.7 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import org.apache.fop.render.Renderer; + +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedInputStream; + +/** + * A simple cached render pages model. + * If the page is prepared for later rendering then this saves + * the page contents to a file and once the page is resolved + * the contents a reloaded. + */ +public class CachedRenderPagesModel extends RenderPagesModel { + private Map pageMap = new HashMap(); + + /** + * Create a new render pages model with the given renderer. + * @param rend the renderer to render pages to + */ + public CachedRenderPagesModel(Renderer rend) { + super(rend); + } + + /** + * Check prepared pages + * If a page is resolved it loads the page contents from + * the file. + * + * @param newpage the new page being added + * @return true if the current page should be rendered + * false if the renderer doesn't support out of order + * rendering and there are pending pages + */ + protected boolean checkPreparedPages(PageViewport newpage) { + for (Iterator iter = prepared.iterator(); iter.hasNext();) { + PageViewport p = (PageViewport)iter.next(); + if (p.isResolved()) { + if (p != newpage) { + try { + // load page from cache + String name = (String)pageMap.get(p); + File temp = new File(name); + System.out.println("page serialized to: " + temp.length()); + ObjectInputStream in = new ObjectInputStream( + new BufferedInputStream( + new FileInputStream(temp))); + p.loadPage(in); + in.close(); + temp.delete(); + pageMap.remove(p); + } catch (Exception e) { + e.printStackTrace(); + } + } + + try { + renderer.renderPage(p); + } catch (Exception e) { + // use error handler to handle this FOP or IO Exception + e.printStackTrace(); + } + p.clear(); + iter.remove(); + } else { + if (!renderer.supportsOutOfOrder()) { + break; + } + } + } + if (newpage != null && newpage.getPage() != null) { + savePage(newpage); + } + return renderer.supportsOutOfOrder() || prepared.isEmpty(); + } + + /** + * Save a page. + * It saves the contents of the page to a file. + * + * @param page the page to prepare + */ + protected void savePage(PageViewport page) { + try { + // save page to cache + ObjectOutputStream tempstream; + String fname = "page" + page.toString() + ".ser"; + tempstream = new ObjectOutputStream(new BufferedOutputStream( + new FileOutputStream(fname))); + page.savePage(tempstream); + tempstream.close(); + pageMap.put(page, fname); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + diff --git a/src/java/org/apache/fop/area/Flow.java b/src/java/org/apache/fop/area/Flow.java new file mode 100644 index 000000000..ab1604e6a --- /dev/null +++ b/src/java/org/apache/fop/area/Flow.java @@ -0,0 +1,63 @@ +/* + * $Id: Flow.java,v 1.5 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * The normal flow reference area class. + * This area contains a list of block areas from the flow. + */ +public class Flow extends BlockParent { + // the list of blocks created from the flow + private int stacking = TB; + private int width; + +} + diff --git a/src/java/org/apache/fop/area/Footnote.java b/src/java/org/apache/fop/area/Footnote.java new file mode 100644 index 000000000..46105f75a --- /dev/null +++ b/src/java/org/apache/fop/area/Footnote.java @@ -0,0 +1,88 @@ +/* + * $Id: Footnote.java,v 1.6 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +// may combine with before float into a conditional area + +/** + * Footnote reference area. + * This areas holds footnote areas and an optional separator area. + */ +public class Footnote extends BlockParent { + private Block separator = null; + + // footnote has an optional separator + // and a list of sub block areas that can be added/removed + + // this is the relative position of the footnote inside + // the body region + private int top; + + /** + * Set the separator area for this footnote. + * + * @param sep the separator area + */ + public void setSeparator(Block sep) { + separator = sep; + } + + /** + * Get the separator area for this footnote area. + * + * @return the separator area + */ + public Block getSeparator() { + return separator; + } + +} + diff --git a/src/java/org/apache/fop/area/LineArea.java b/src/java/org/apache/fop/area/LineArea.java new file mode 100644 index 000000000..e83f08941 --- /dev/null +++ b/src/java/org/apache/fop/area/LineArea.java @@ -0,0 +1,147 @@ +/* + * $Id: LineArea.java,v 1.12 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import org.apache.fop.area.inline.InlineArea; + +import java.util.ArrayList; +import java.util.List; + +/** + * The line area. + * This is a line area that contains inline areas. + */ +public class LineArea extends Area { + private int stacking = LR; + // contains inline areas + // has start indent and length, dominant baseline, height + private int startIndent; + private int length; + + private int lineHeight; + // this is the offset for the dominant baseline + private int baseLine; + + // this class can contain the dominant char styling info + // this means that many renderers can optimise a bit + + private List inlineAreas = new ArrayList(); + + /** + * Set the height of this line area. + * + * @param height the height of the line area + */ + public void setHeight(int height) { + lineHeight = height; + } + + /** + * Get the height of this line area. + * + * @return the height of the line area + */ + public int getHeight() { + return lineHeight; + } + + /** + * Add a child area to this line area. + * + * @param childArea the inline child area to add + */ + public void addChild(Area childArea) { + if (childArea instanceof InlineArea) { + addInlineArea((InlineArea)childArea); + } + } + + /** + * Add an inline child area to this line area. + * + * @param area the inline child area to add + */ + public void addInlineArea(InlineArea area) { + inlineAreas.add(area); + } + + /** + * Get the inline child areas of this line area. + * + * @return the list of inline areas + */ + public List getInlineAreas() { + return inlineAreas; + } + + /** + * Set the start indent of this line area. + * The start indent is used for offsetting the start of + * the inline areas for alignment or other indents. + * + * @param si the start indent value + */ + public void setStartIndent(int si) { + startIndent = si; + } + + /** + * Get the start indent of this line area. + * The start indent is used for offsetting the start of + * the inline areas for alignment or other indents. + * + * @return the start indent value + */ + public int getStartIndent() { + return startIndent; + } +} + diff --git a/src/java/org/apache/fop/area/LineTrait.java b/src/java/org/apache/fop/area/LineTrait.java new file mode 100644 index 000000000..08026d404 --- /dev/null +++ b/src/java/org/apache/fop/area/LineTrait.java @@ -0,0 +1,60 @@ +/* + * $Id: LineTrait.java,v 1.3 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * Traits for a range of areas in a line. + * Not sure if this is needed. + */ +public class LineTrait extends Trait { + private int[] range; +} + diff --git a/src/java/org/apache/fop/area/MainReference.java b/src/java/org/apache/fop/area/MainReference.java new file mode 100644 index 000000000..7c2362cd2 --- /dev/null +++ b/src/java/org/apache/fop/area/MainReference.java @@ -0,0 +1,101 @@ +/* + * $Id: MainReference.java,v 1.6 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.List; + +/** + * The main body reference area. + * This area that contains the flow via the span areas. + */ +public class MainReference extends Area { + private List spanAreas = new java.util.ArrayList(); + private int columnGap; + private int width; + + /** + * Add a span area to this area. + * + * @param span the span area to add + */ + public void addSpan(Span span) { + spanAreas.add(span); + } + + /** + * Get the span areas from this area. + * + * @return the list of span areas + */ + public List getSpans() { + return spanAreas; + } + + /** + * Get the column gap in millipoints. + * + * @return the column gap in millioints + */ + public int getColumnGap() { + return columnGap; + } + + /** + * Get the width of this reference area. + * + * @return the width + */ + public int getWidth() { + return width; + } + +} + diff --git a/src/java/org/apache/fop/area/Page.java b/src/java/org/apache/fop/area/Page.java new file mode 100644 index 000000000..857a2578e --- /dev/null +++ b/src/java/org/apache/fop/area/Page.java @@ -0,0 +1,166 @@ +/* + * $Id: Page.java,v 1.10 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.io.Serializable; +import java.util.Map; + +/** + * The page. + * This holds the contents of the page. Each region is added. + * The unresolved references area added so that if the page is + * serialized then it will handle the resolving properly after + * being reloaded. + * This is serializable so it can be saved to cache to save + * memory if there are forward references. + * The page is cloneable so the page master can make copies of + * the top level page and regions. + */ +public class Page implements Serializable, Cloneable { + // contains before, start, body, end and after regions + private RegionViewport regionBefore = null; + private RegionViewport regionStart = null; + private RegionViewport regionBody = null; + private RegionViewport regionEnd = null; + private RegionViewport regionAfter = null; + + // temporary map of unresolved objects used when serializing the page + private Map unresolved = null; + + /** + * Set the region on this page. + * + * @param areaclass the area class of the region to set + * @param port the region viewport to set + */ + public void setRegion(int areaclass, RegionViewport port) { + if (areaclass == RegionReference.BEFORE) { + regionBefore = port; + } else if (areaclass == RegionReference.START) { + regionStart = port; + } else if (areaclass == RegionReference.BODY) { + regionBody = port; + } else if (areaclass == RegionReference.END) { + regionEnd = port; + } else if (areaclass == RegionReference.AFTER) { + regionAfter = port; + } + } + + /** + * Get the region from this page. + * + * @param areaclass the region area class + * @return the region viewport or null if none + */ + public RegionViewport getRegion(int areaclass) { + if (areaclass == RegionReference.BEFORE) { + return regionBefore; + } else if (areaclass == RegionReference.START) { + return regionStart; + } else if (areaclass == RegionReference.BODY) { + return regionBody; + } else if (areaclass == RegionReference.END) { + return regionEnd; + } else if (areaclass == RegionReference.AFTER) { + return regionAfter; + } + return null; + } + + /** + * Clone this page. + * This returns a new page with a clone of all the regions. + * + * @return a new clone of this page + */ + public Object clone() { + Page p = new Page(); + if (regionBefore != null) { + p.regionBefore = (RegionViewport)regionBefore.clone(); + } + if (regionStart != null) { + p.regionStart = (RegionViewport)regionStart.clone(); + } + if (regionBody != null) { + p.regionBody = (RegionViewport)regionBody.clone(); + } + if (regionEnd != null) { + p.regionEnd = (RegionViewport)regionEnd.clone(); + } + if (regionAfter != null) { + p.regionAfter = (RegionViewport)regionAfter.clone(); + } + + return p; + } + + /** + * Set the unresolved references on this page for serializing. + * + * @param unres the map of unresolved objects + */ + public void setUnresolvedReferences(Map unres) { + unresolved = unres; + } + + /** + * Get the map unresolved references from this page. + * This should be called after deserializing to retrieve + * the map of unresolved references that were serialized. + * + * @return the de-serialized map of unresolved objects + */ + public Map getUnresolvedReferences() { + return unresolved; + } +} + diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java new file mode 100644 index 000000000..df8c4bed0 --- /dev/null +++ b/src/java/org/apache/fop/area/PageViewport.java @@ -0,0 +1,407 @@ +/* + * $Id: PageViewport.java,v 1.16 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.awt.geom.Rectangle2D; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +import org.apache.fop.fo.properties.RetrievePosition; + +/** + * Page viewport that specifies the viewport area and holds the page contents. + * This is the top level object for a page and remains valid for the life + * of the document and the area tree. + * This object may be used as a key to reference a page. + * This is the level that creates the page. + * The page (reference area) is then rendered inside the page object + */ +public class PageViewport implements Resolveable, Cloneable { + + private Page page; + private Rectangle2D viewArea; + private boolean clip = false; + private String pageNumber = null; + + // list of id references and the rectangle on the page + private Map idReferences = null; + + // this keeps a list of currently unresolved areas or extensions + // once the thing is resolved it is removed + // when this is empty the page can be rendered + private Map unresolved = null; + + private Map pendingResolved = null; + + // hashmap of markers for this page + // start and end are added by the fo that contains the markers + private Map markerFirstStart = null; + private Map markerLastStart = null; + private Map markerFirstAny = null; + private Map markerLastEnd = null; + private Map markerLastAny = null; + + /** + * Create a page viewport. + * @param p the page reference area that holds the contents + * @param bounds the bounds of this viewport + */ + public PageViewport(Page p, Rectangle2D bounds) { + page = p; + viewArea = bounds; + } + + /** + * Set if this viewport should clip. + * @param c true if this viewport should clip + */ + public void setClip(boolean c) { + clip = c; + } + + /** + * Get the view area rectangle of this viewport. + * @return the rectangle for this viewport + */ + public Rectangle2D getViewArea() { + return viewArea; + } + + /** + * Get the page reference area with the contents. + * @return the page reference area + */ + public Page getPage() { + return page; + } + + /** + * Set the page number for this page. + * @param num the string representing the page number + */ + public void setPageNumber(String num) { + pageNumber = num; + } + + /** + * Get the page number of this page. + * @return the string that represents this page + */ + public String getPageNumber() { + return pageNumber; + } + + /** + * Get the key for this page viewport. + * This is used so that a serializable key can be used to + * lookup the page or some other reference. + * + * @return a unique page viewport key for this area tree + */ + public String getKey() { + return toString(); + } + + /** + * Add an unresolved id to this page. + * All unresolved ids for the contents of this page are + * added to this page. This is so that the resolvers can be + * serialized with the page to preserve the proper function. + * @param id the id of the reference + * @param res the resolver of the reference + */ + public void addUnresolvedID(String id, Resolveable res) { + if (unresolved == null) { + unresolved = new HashMap(); + } + List list = (List)unresolved.get(id); + if (list == null) { + list = new ArrayList(); + unresolved.put(id, list); + } + list.add(res); + } + + /** + * Check if this page has been fully resolved. + * @return true if the page is resolved and can be rendered + */ + public boolean isResolved() { + return unresolved == null; + } + + /** + * Get the id references for this page. + * @return always null + */ + public String[] getIDs() { + return null; + } + + /** + * This resolves reference with a list of pages. + * The pages (PageViewport) contain the rectangle of the area. + * @param id the id to resolve + * @param pages the list of pages with the id area + * may be null if not found + */ + public void resolve(String id, List pages) { + if (page == null) { + if (pendingResolved == null) { + pendingResolved = new HashMap(); + } + pendingResolved.put(id, pages); + } else { + if (unresolved != null) { + List todo = (List)unresolved.get(id); + if (todo != null) { + for (int count = 0; count < todo.size(); count++) { + Resolveable res = (Resolveable)todo.get(count); + res.resolve(id, pages); + } + } + } + } + if (unresolved != null) { + unresolved.remove(id); + if (unresolved.isEmpty()) { + unresolved = null; + } + } + } + + /** + * Add the markers for this page. + * Only the required markers are kept. + * For "first-starting-within-page" it adds the markers + * that are starting only if the marker class name is not + * already added. + * For "first-including-carryover" it adds any starting marker + * if the marker class name is not already added. + * For "last-starting-within-page" it adds all marks that + * are starting, replacing earlier markers. + * For "last-ending-within-page" it adds all markers that + * are ending, replacing earlier markers. + * + * Should this logic be placed in the Page layout manager. + * + * @param marks the map of markers to add + * @param start if the area being added is starting or ending + * @param isfirst isfirst or islast flag + */ + public void addMarkers(Map marks, boolean start, boolean isfirst) { + if (start) { + if (isfirst) { + if (markerFirstStart == null) { + markerFirstStart = new HashMap(); + } + if (markerFirstAny == null) { + markerFirstAny = new HashMap(); + } + // only put in new values, leave current + for (Iterator iter = marks.keySet().iterator(); iter.hasNext();) { + Object key = iter.next(); + if (!markerFirstStart.containsKey(key)) { + markerFirstStart.put(key, marks.get(key)); + } + if (!markerFirstAny.containsKey(key)) { + markerFirstAny.put(key, marks.get(key)); + } + } + if (markerLastStart == null) { + markerLastStart = new HashMap(); + } + // replace all + markerLastStart.putAll(marks); + + } else { + if (markerFirstAny == null) { + markerFirstAny = new HashMap(); + } + // only put in new values, leave current + for (Iterator iter = marks.keySet().iterator(); iter.hasNext();) { + Object key = iter.next(); + if (!markerFirstAny.containsKey(key)) { + markerFirstAny.put(key, marks.get(key)); + } + } + } + } else { + if (!isfirst) { + if (markerLastEnd == null) { + markerLastEnd = new HashMap(); + } + // replace all + markerLastEnd.putAll(marks); + } + if (markerLastAny == null) { + markerLastAny = new HashMap(); + } + // replace all + markerLastAny.putAll(marks); + } + } + + /** + * Get a marker from this page. + * This will retrieve a marker with the class name + * and position. + * + * @param name The class name of the marker to retrieve + * @param pos the position to retrieve + * @return Object the marker found or null + */ + public Object getMarker(String name, int pos) { + Object mark = null; + switch (pos) { + case RetrievePosition.FSWP: + if (markerFirstStart != null) { + mark = markerFirstStart.get(name); + } + if (mark == null && markerFirstAny != null) { + mark = markerFirstAny.get(name); + } + break; + case RetrievePosition.FIC: + if (markerFirstAny != null) { + mark = markerFirstAny.get(name); + } + break; + case RetrievePosition.LSWP: + if (markerLastStart != null) { + mark = markerLastStart.get(name); + } + if (mark == null && markerLastAny != null) { + mark = markerLastAny.get(name); + } + break; + case RetrievePosition.LEWP: + if (markerLastEnd != null) { + mark = markerLastEnd.get(name); + } + if (mark == null && markerLastAny != null) { + mark = markerLastAny.get(name); + } + break; + } + return mark; + } + + /** + * Save the page contents to an object stream. + * The map of unresolved references are set on the page so that + * the resolvers can be properly serialized and reloaded. + * @param out the object output stream to write the contents + * @throws Exception if there is a problem saving the page + */ + public void savePage(ObjectOutputStream out) throws Exception { + // set the unresolved references so they are serialized + page.setUnresolvedReferences(unresolved); + out.writeObject(page); + page = null; + } + + /** + * Load the page contents from an object stream. + * This loads the page contents from the stream and + * if there are any unresolved references that were resolved + * while saved they will be resolved on the page contents. + * @param in the object input stream to read the page from + * @throws Exception if there is an error loading the page + */ + public void loadPage(ObjectInputStream in) throws Exception { + page = (Page) in.readObject(); + unresolved = page.getUnresolvedReferences(); + if (unresolved != null && pendingResolved != null) { + for (Iterator iter = pendingResolved.keySet().iterator(); + iter.hasNext();) { + String id = (String) iter.next(); + resolve(id, (List)pendingResolved.get(id)); + } + pendingResolved = null; + } + } + + /** + * Clone this page. + * Used by the page master to create a copy of an original page. + * @return a copy of this page and associated viewports + */ + public Object clone() { + Page p = (Page)page.clone(); + PageViewport ret = new PageViewport(p, (Rectangle2D)viewArea.clone()); + return ret; + } + + /** + * Clear the page contents to save memory. + * This object is kept for the life of the area tree since + * it holds id and marker information and is used as a key. + */ + public void clear() { + page = null; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append("PageViewport: page="); + sb.append(getPageNumber()); + return sb.toString(); + } +} diff --git a/src/java/org/apache/fop/area/RegionReference.java b/src/java/org/apache/fop/area/RegionReference.java new file mode 100644 index 000000000..f83e8ded0 --- /dev/null +++ b/src/java/org/apache/fop/area/RegionReference.java @@ -0,0 +1,164 @@ +/* + * $Id: RegionReference.java,v 1.10 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is a region reference area for the page regions. + * This area represents a region on the page. It is cloneable + * so the page master can make copies from the original page and regions. + */ +public class RegionReference extends Area implements Cloneable { + /** + * The before region. + */ + public static final int BEFORE = 0; + + /** + * The start region. + */ + public static final int START = 1; + + /** + * The body region. + */ + public static final int BODY = 2; + + /** + * The end region. + */ + public static final int END = 3; + + /** + * The after region. + */ + public static final int AFTER = 4; + + private int regionClass = BEFORE; + private CTM ctm; + // the list of block areas from the static flow + private List blocks = new ArrayList(); + + /** + * Create a new region reference area. + * + * @param type the region class type + */ + public RegionReference(int type) { + regionClass = type; + } + + /** + * Set the Coordinate Transformation Matrix which transforms content + * coordinates in this region reference area which are specified in + * terms of "start" and "before" into coordinates in a system which + * is positioned in "absolute" directions (with origin at lower left of + * the region reference area. + * + * @param ctm the current transform to position this region + */ + public void setCTM(CTM ctm) { + this.ctm = ctm; + } + + /** + * Get the current transform of this region. + * + * @return ctm the current transform to position this region + */ + public CTM getCTM() { + return this.ctm; + } + + /** + * Get the block in this region. + * + * @return the list of blocks in this region + */ + public List getBlocks() { + return blocks; + } + + /** + * Get the region class of this region. + * + * @return the region class + */ + public int getRegionClass() { + return regionClass; + } + + /** + * Add a block area to this region reference area. + * + * @param block the block area to add + */ + public void addBlock(Block block) { + blocks.add(block); + } + + /** + * Clone this region. + * This is used when cloning the page by the page master. + * The blocks are not copied since the master will have no blocks. + * + * @return a copy of this region reference area + */ + public Object clone() { + RegionReference rr = new RegionReference(regionClass); + rr.ctm = ctm; + rr.setIPD(getIPD()); + return rr; + } + +} diff --git a/src/java/org/apache/fop/area/RegionViewport.java b/src/java/org/apache/fop/area/RegionViewport.java new file mode 100644 index 000000000..b4f5d5a85 --- /dev/null +++ b/src/java/org/apache/fop/area/RegionViewport.java @@ -0,0 +1,147 @@ +/* + * $Id: RegionViewport.java,v 1.9 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.HashMap; + +/** + * Region Viewport reference area. + * This area is the viewport for a region and contains a region area. + */ +public class RegionViewport extends Area implements Cloneable { + // this rectangle is relative to the page + private RegionReference region; + private Rectangle2D viewArea; + private boolean clip = false; + + /** + * Create a new region viewport. + * + * @param viewArea the view area of this viewport + */ + public RegionViewport(Rectangle2D viewArea) { + this.viewArea = viewArea; + } + + /** + * Set the region for this region viewport. + * + * @param reg the child region inside this viewport + */ + public void setRegion(RegionReference reg) { + region = reg; + } + + /** + * Get the region for this region viewport. + * + * @return the child region inside this viewport + */ + public RegionReference getRegion() { + return region; + } + + /** + * Set the clipping for this region viewport. + * + * @param c the clipping value + */ + public void setClip(boolean c) { + clip = c; + } + + /** + * Get the view area of this viewport. + * + * @return the viewport rectangle area + */ + public Rectangle2D getViewArea() { + return viewArea; + } + + private void writeObject(java.io.ObjectOutputStream out) + throws IOException { + out.writeFloat((float) viewArea.getX()); + out.writeFloat((float) viewArea.getY()); + out.writeFloat((float) viewArea.getWidth()); + out.writeFloat((float) viewArea.getHeight()); + out.writeBoolean(clip); + out.writeObject(props); + out.writeObject(region); + } + + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException { + viewArea = new Rectangle2D.Float(in.readFloat(), in.readFloat(), + in.readFloat(), in.readFloat()); + clip = in.readBoolean(); + props = (HashMap)in.readObject(); + setRegion((RegionReference) in.readObject()); + } + + /** + * Clone this region viewport. + * Used when creating a copy from the page master. + * + * @return a new copy of this region viewport + */ + public Object clone() { + RegionViewport rv = new RegionViewport((Rectangle2D)viewArea.clone()); + rv.region = (RegionReference)region.clone(); + if (props != null) { + rv.props = (HashMap)props.clone(); + } + return rv; + } +} + diff --git a/src/java/org/apache/fop/area/RenderPagesModel.java b/src/java/org/apache/fop/area/RenderPagesModel.java new file mode 100644 index 000000000..0cedeb85c --- /dev/null +++ b/src/java/org/apache/fop/area/RenderPagesModel.java @@ -0,0 +1,223 @@ +/* + * $Id: RenderPagesModel.java,v 1.3 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +// FOP +import org.apache.fop.render.Renderer; + +// Java +import java.util.List; +import java.util.Iterator; + +/** + * This uses the store pages model to store the pages + * each page is either rendered if ready or prepared + * for later rendering. + * Once a page is rendered it is cleared to release the + * contents but the PageViewport is retained. So even + * though the pages are stored the contents are discarded. + */ +public class RenderPagesModel extends StorePagesModel { + /** + * The renderer that will render the pages. + */ + protected Renderer renderer; + /** + * Pages that have been prepared but not rendered yet. + */ + protected List prepared = new java.util.ArrayList(); + private List pendingExt = new java.util.ArrayList(); + private List endDocExt = new java.util.ArrayList(); + + /** + * Create a new render pages model with the given renderer. + * @param rend the renderer to render pages to + */ + public RenderPagesModel(Renderer rend) { + renderer = rend; + } + + /** + * Start a new page sequence. + * This tells the renderer that a new page sequence has + * started with the given title. + * @param title the title of the new page sequence + */ + public void startPageSequence(Title title) { + super.startPageSequence(title); + renderer.startPageSequence(title); + } + + /** + * Add a page to the render page model. + * If the page is finished it can be rendered immediately. + * If the page needs resolving then if the renderer supports + * out of order rendering it can prepare the page. Otherwise + * the page is added to a queue. + * @param page the page to add to the model + */ + public void addPage(PageViewport page) { + super.addPage(page); + + // for links the renderer needs to prepare the page + // it is more appropriate to do this after queued pages but + // it will mean that the renderer has not prepared a page that + // could be referenced + boolean done = renderer.supportsOutOfOrder() && page.isResolved(); + if (done) { + try { + renderer.renderPage(page); + } catch (Exception e) { + // use error handler to handle this FOP or IO Exception + e.printStackTrace(); + } + page.clear(); + } else { + preparePage(page); + } + + + // check prepared pages + boolean cont = checkPreparedPages(page); + + if (cont) { + renderExtensions(pendingExt); + pendingExt.clear(); + } + } + + /** + * Check prepared pages + * + * @param newpage the new page being added + * @return true if the current page should be rendered + * false if the renderer doesn't support out of order + * rendering and there are pending pages + */ + protected boolean checkPreparedPages(PageViewport newpage) { + for (Iterator iter = prepared.iterator(); iter.hasNext();) { + PageViewport p = (PageViewport)iter.next(); + if (p.isResolved()) { + try { + renderer.renderPage(p); + } catch (Exception e) { + // use error handler to handle this FOP or IO Exception + e.printStackTrace(); + } + p.clear(); + iter.remove(); + } else { + // if keeping order then stop at first page not resolved + if (!renderer.supportsOutOfOrder()) { + break; + } + } + } + return renderer.supportsOutOfOrder() || prepared.isEmpty(); + } + + /** + * Prepare a page. + * An unresolved page can be prepared if the renderer supports + * it and the page will be rendered later. + * @param page the page to prepare + */ + protected void preparePage(PageViewport page) { + if (renderer.supportsOutOfOrder()) { + renderer.preparePage(page); + } + prepared.add(page); + } + + /** + * Add an extension to this model. + * If handle immediately then send directly to the renderer. + * The after page ones are handled after the next page is added. + * End of document extensions are added to a list to be + * handled at the end. + * @param ext the extension + * @param when when to render the extension + */ + public void addExtension(TreeExt ext, int when) { + switch(when) { + case TreeExt.IMMEDIATELY: + renderer.renderExtension(ext); + break; + case TreeExt.AFTER_PAGE: + pendingExt.add(ext); + break; + case TreeExt.END_OF_DOC: + endDocExt.add(ext); + break; + } + } + + private void renderExtensions(List list) { + for (int count = 0; count < list.size(); count++) { + TreeExt ext = (TreeExt)list.get(count); + renderer.renderExtension(ext); + } + } + + /** + * End the document. Render any end document extensions. + */ + public void endDocument() { + // render any pages that had unresolved ids + checkPreparedPages(null); + + renderExtensions(pendingExt); + pendingExt.clear(); + + renderExtensions(endDocExt); + } +} + diff --git a/src/java/org/apache/fop/area/Resolveable.java b/src/java/org/apache/fop/area/Resolveable.java new file mode 100644 index 000000000..7687a2bf3 --- /dev/null +++ b/src/java/org/apache/fop/area/Resolveable.java @@ -0,0 +1,87 @@ +/* + * $Id: Resolveable.java,v 1.5 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.List; + +/** + * Resolveable Interface. + * Classes that implement this can be resolved when + * an id is added to the area tree. + */ +public interface Resolveable { + + /** + * Check if this area has been resolved. + * + * @return true once this area is resolved + */ + boolean isResolved(); + + /** + * Get the array of id references of this resolveable object. + * If this object contains child resolveables that are + * resolved through this then it should return the id's of + * the child also. + * + * @return the id references for resolving this object + */ + String[] getIDs(); + + /** + * This resolves reference with a list of pages. + * The pages (PageViewport) contain the rectangle of the area. + * @param id the id to resolve + * @param pages the list of pages with the id area + * may be null if not found + */ + void resolve(String id, List pages); +} diff --git a/src/java/org/apache/fop/area/Span.java b/src/java/org/apache/fop/area/Span.java new file mode 100644 index 000000000..04258bfb0 --- /dev/null +++ b/src/java/org/apache/fop/area/Span.java @@ -0,0 +1,112 @@ +/* + * $Id: Span.java,v 1.8 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import java.util.List; + +/** + * The span reference area. + * This is a reference area block area with 0 border and padding + * The span reference areas are stacked inside the main reference area. + */ +public class Span extends Area { + // the list of flow reference areas in this span area + private List flowAreas; + private int height; + + /** + * Create a span area with the number of columns for this span area. + * + * @param cols the number of columns in the span + */ + public Span(int cols) { + flowAreas = new java.util.ArrayList(cols); + } + + /** + * Add the flow area to this span area. + * + * @param flow the flow area to add + */ + public void addFlow(Flow flow) { + flowAreas.add(flow); + } + + /** + * Get the column count for this span area. + * + * @return the number of columns in this span area + */ + public int getColumnCount() { + return flowAreas.size(); + } + + /** + * Get the height of this span area. + * + * @return the height of this span area + */ + public int getHeight() { + return height; + } + + /** + * Get the flow area for a particular column. + * + * @param count the column number for the flow + * @return the flow area for the requested column + */ + public Flow getFlow(int count) { + return (Flow) flowAreas.get(count); + } + +} + diff --git a/src/java/org/apache/fop/area/StorePagesModel.java b/src/java/org/apache/fop/area/StorePagesModel.java new file mode 100644 index 000000000..f75e2d98a --- /dev/null +++ b/src/java/org/apache/fop/area/StorePagesModel.java @@ -0,0 +1,179 @@ +/* + * $Id: StorePagesModel.java,v 1.3 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +// Java +import java.util.List; + +/** + * This class stores all the pages in the document + * for interactive agents. + * The pages are stored and can be retrieved in any order. + */ +public class StorePagesModel extends AreaTreeModel { + private List pageSequence = null; + private List titles = new java.util.ArrayList(); + private List currSequence; + private List extensions = new java.util.ArrayList(); + + /** + * Create a new store pages model + */ + public StorePagesModel() { + } + + /** + * Start a new page sequence. + * This creates a new list for the pages in the new page sequence. + * @param title the title of the page sequence. + */ + public void startPageSequence(Title title) { + titles.add(title); + if (pageSequence == null) { + pageSequence = new java.util.ArrayList(); + } + currSequence = new java.util.ArrayList(); + pageSequence.add(currSequence); + } + + /** + * Add a page. + * @param page the page to add to the current page sequence + */ + public void addPage(PageViewport page) { + currSequence.add(page); + } + + /** + * Get the page sequence count. + * @return the number of page sequences in the document. + */ + public int getPageSequenceCount() { + return pageSequence.size(); + } + + /** + * Get the title for a page sequence. + * @param count the page sequence count + * @return the title of the page sequence + */ + public Title getTitle(int count) { + return (Title) titles.get(count); + } + + /** + * Get the page count. + * @param seq the page sequence to count. + * @return returns the number of pages in a page sequence + */ + public int getPageCount(int seq) { + List sequence = (List) pageSequence.get(seq); + return sequence.size(); + } + + /** + * Get the page for a position in the document. + * @param seq the page sequence number + * @param count the page count in the sequence + * @return the PageViewport for the particular page + */ + public PageViewport getPage(int seq, int count) { + List sequence = (List) pageSequence.get(seq); + return (PageViewport) sequence.get(count); + } + + /** + * Add an extension to the store page model. + * The extension is stored so that it can be retrieved in the + * appropriate position. + * @param ext the extension to add + * @param when when the extension should be handled + */ + public void addExtension(TreeExt ext, int when) { + int seq, page; + switch(when) { + case TreeExt.IMMEDIATELY: + seq = pageSequence == null ? 0 : pageSequence.size(); + page = currSequence == null ? 0 : currSequence.size(); + break; + case TreeExt.AFTER_PAGE: + break; + case TreeExt.END_OF_DOC: + break; + } + extensions.add(ext); + } + + /** + * Get the list of extensions that apply at a particular + * position in the document. + * @param seq the page sequence number + * @param count the page count in the sequence + * @return the list of extensions + */ + public List getExtensions(int seq, int count) { + return null; + } + + /** + * Get the end of document extensions for this stroe pages model. + * @return the list of end extensions + */ + public List getEndExtensions() { + return extensions; + } + + /** + * End document, do nothing. + */ + public void endDocument() { + } +} diff --git a/src/java/org/apache/fop/area/Title.java b/src/java/org/apache/fop/area/Title.java new file mode 100644 index 000000000..e90c57b9d --- /dev/null +++ b/src/java/org/apache/fop/area/Title.java @@ -0,0 +1,60 @@ +/* + * $Id: Title.java,v 1.4 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * The title area. + * This area holds the inline areas from the page-sequence + * title element. + */ +public class Title extends LineArea { +} + diff --git a/src/java/org/apache/fop/area/Trait.java b/src/java/org/apache/fop/area/Trait.java new file mode 100644 index 000000000..3cf8ba74e --- /dev/null +++ b/src/java/org/apache/fop/area/Trait.java @@ -0,0 +1,475 @@ +/* + * $Id: Trait.java,v 1.13 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.traits.BorderProps; + +import java.io.Serializable; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +// properties should be serialized by the holder +/** + * Area traits used for rendering. + * This class represents an area trait that specifies a value for rendering. + */ +public class Trait implements Serializable { + /** + * Id reference line, not resolved. + * not sure if this is needed. + */ + public static final Integer ID_LINK = new Integer(0); + + /** + * Internal link trait. + * This is resolved and provides a link to an internal area. + */ + public static final Integer INTERNAL_LINK = new Integer(1); //resolved + + /** + * External link. A URL link to an external resource. + */ + public static final Integer EXTERNAL_LINK = new Integer(2); + + /** + * The font name from the font setup. + */ + public static final Integer FONT_NAME = new Integer(3); + + /** + * Font size for the current font. + */ + public static final Integer FONT_SIZE = new Integer(4); + + /** + * The current colour. + */ + public static final Integer COLOR = new Integer(7); + + /** + * Don't think this is necessary. + */ + public static final Integer ID_AREA = new Integer(8); + + /** + * Background trait for an area. + */ + public static final Integer BACKGROUND = new Integer(9); + + /** + * Underline trait used when rendering inline parent. + */ + public static final Integer UNDERLINE = new Integer(10); + + /** + * Overline trait used when rendering inline parent. + */ + public static final Integer OVERLINE = new Integer(11); + + /** + * Linethrough trait used when rendering inline parent. + */ + public static final Integer LINETHROUGH = new Integer(12); + + /** + * Shadow offset. + */ + public static final Integer OFFSET = new Integer(13); + + /** + * The shadow for text. + */ + public static final Integer SHADOW = new Integer(14); + + /** + * The border start. + */ + public static final Integer BORDER_START = new Integer(15); + + /** + * The border end. + */ + public static final Integer BORDER_END = new Integer(16); + + /** + * The border before. + */ + public static final Integer BORDER_BEFORE = new Integer(17); + + /** + * The border after. + */ + public static final Integer BORDER_AFTER = new Integer(18); + + /** + * The padding start. + */ + public static final Integer PADDING_START = new Integer(19); + + /** + * The padding end. + */ + public static final Integer PADDING_END = new Integer(20); + + /** + * The padding before. + */ + public static final Integer PADDING_BEFORE = new Integer(21); + + /** + * The padding after. + */ + public static final Integer PADDING_AFTER = new Integer(22); + + private static final Map TRAIT_INFO = new HashMap(); + + private static class TraitInfo { + private String name; + private Class clazz; // Class of trait data + + public TraitInfo(String name, Class clazz) { + this.name = name; + this.clazz = clazz; + } + + public String getName() { + return this.name; + } + + public Class getClazz() { + return this.clazz; + } + } + + static { + // Create a hashmap mapping trait code to name for external representation + TRAIT_INFO.put(ID_LINK, new TraitInfo("id-link", String.class)); + TRAIT_INFO.put(INTERNAL_LINK, + new TraitInfo("internal-link", String.class)); + TRAIT_INFO.put(EXTERNAL_LINK, + new TraitInfo("external-link", String.class)); + TRAIT_INFO.put(FONT_NAME, + new TraitInfo("font-family", String.class)); + TRAIT_INFO.put(FONT_SIZE, + new TraitInfo("font-size", Integer.class)); + TRAIT_INFO.put(COLOR, new TraitInfo("color", String.class)); + TRAIT_INFO.put(ID_AREA, new TraitInfo("id-area", String.class)); + TRAIT_INFO.put(BACKGROUND, + new TraitInfo("background", Background.class)); + TRAIT_INFO.put(UNDERLINE, + new TraitInfo("underline", Boolean.class)); + TRAIT_INFO.put(OVERLINE, + new TraitInfo("overline", Boolean.class)); + TRAIT_INFO.put(LINETHROUGH, + new TraitInfo("linethrough", Boolean.class)); + TRAIT_INFO.put(OFFSET, new TraitInfo("offset", Integer.class)); + TRAIT_INFO.put(SHADOW, new TraitInfo("shadow", Integer.class)); + TRAIT_INFO.put(BORDER_START, + new TraitInfo("border-start", BorderProps.class)); + TRAIT_INFO.put(BORDER_END, + new TraitInfo("border-end", BorderProps.class)); + TRAIT_INFO.put(BORDER_BEFORE, + new TraitInfo("border-before", BorderProps.class)); + TRAIT_INFO.put(BORDER_AFTER, + new TraitInfo("border-after", BorderProps.class)); + TRAIT_INFO.put(PADDING_START, + new TraitInfo("padding-start", Integer.class)); + TRAIT_INFO.put(PADDING_END, + new TraitInfo("padding-end", Integer.class)); + TRAIT_INFO.put(PADDING_BEFORE, + new TraitInfo("padding-before", Integer.class)); + TRAIT_INFO.put(PADDING_AFTER, + new TraitInfo("padding-after", Integer.class)); + } + + /** + * Get the trait name for a trait code. + * + * @param traitCode the trait code to get the name for + * @return the trait name + */ + public static String getTraitName(Object traitCode) { + Object obj = TRAIT_INFO.get(traitCode); + if (obj != null) { + return ((TraitInfo) obj).getName(); + } else { + return "unknown-trait-" + traitCode.toString(); + } + } + + /** + * Get the trait code for a trait name. + * + * @param sTraitName the name of the trait to find + * @return the trait code object + */ + public static Object getTraitCode(String sTraitName) { + Iterator iter = TRAIT_INFO.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry) iter.next(); + TraitInfo ti = (TraitInfo) entry.getValue(); + if (ti != null && ti.getName().equals(sTraitName)) { + return entry.getKey(); + } + } + return null; + } + + /** + * Get the data storage class for the trait. + * + * @param oTraitCode the trait code to lookup + * @return the class type for the trait + */ + private static Class getTraitClass(Object oTraitCode) { + TraitInfo ti = (TraitInfo) TRAIT_INFO.get(oTraitCode); + return (ti != null ? ti.getClazz() : null); + } + + /** + * The type of trait for an area. + */ + private Object propType; + + /** + * The data value of the trait. + */ + private Object data; + + /** + * Create a new empty trait. + */ + public Trait() { + this.propType = null; + this.data = null; + } + + /** + * Create a trait with the value and type. + * + * @param propType the type of trait + * @param data the data value + */ + public Trait(Object propType, Object data) { + this.propType = propType; + this.data = data; + } + + /** + * Returns the trait data value. + * @return the trait data value + */ + public Object getData() { + return this.data; + } + + /** + * Returns the property type. + * @return the property type + */ + public Object getPropType() { + return this.propType; + } + + /** + * Return the string for debugging. + * @see java.lang.Object#toString() + */ + public String toString() { + return data.toString(); + } + + /** + * Make a trait value. + * + * @param oCode trait code + * @param sTraitValue trait value as String + * @return the trait value as object + */ + public static Object makeTraitValue(Object oCode, String sTraitValue) { + // Get the code from the name + // See what type of object it is + // Convert string value to an object of that type + Class tclass = getTraitClass(oCode); + if (tclass == null) { + return null; + } + if (tclass.equals(String.class)) { + return sTraitValue; + } + if (tclass.equals(Integer.class)) { + return new Integer(sTraitValue); + } + // See if the class has a constructor from string or can read from a string + try { + Object o = tclass.newInstance(); + //return o.fromString(sTraitValue); + } catch (IllegalAccessException e1) { + System.err.println("Can't create instance of " + + tclass.getName()); + return null; + } catch (InstantiationException e2) { + System.err.println("Can't create instance of " + + tclass.getName()); + return null; + } + + + return null; + } + + /** + * Background trait structure. + * Used for storing back trait information which are related. + */ + public static class Background implements Serializable { + + /** The background color if any. */ + private ColorType color = null; + + /** The background image url if any. */ + private String url = null; + + /** Background repeat enum for images. */ + private int repeat; + + /** Background horizontal offset for images. */ + private int horiz; + + /** Background vertical offset for images. */ + private int vertical; + + /** + * Returns the background color. + * @return background color, null if n/a + */ + public ColorType getColor() { + return color; + } + + /** + * Returns the horizontal offset for images. + * @return the horizontal offset + */ + public int getHoriz() { + return horiz; + } + + /** + * Returns the image repetition behaviour for images. + * @return the image repetition behaviour + */ + public int getRepeat() { + return repeat; + } + + /** + * Returns the URL to the background image + * @return URL to the background image, null if n/a + */ + public String getURL() { + return url; + } + + /** + * Returns the vertical offset for images. + * @return the vertical offset + */ + public int getVertical() { + return vertical; + } + + /** + * Sets the color. + * @param color The color to set + */ + public void setColor(ColorType color) { + this.color = color; + } + + /** + * Sets the horizontal offset. + * @param horiz The horizontal offset to set + */ + public void setHoriz(int horiz) { + this.horiz = horiz; + } + + /** + * Sets the image repetition behaviour for images. + * @param repeat The image repetition behaviour to set + */ + public void setRepeat(int repeat) { + this.repeat = repeat; + } + + /** + * Sets the URL to the background image. + * @param url The URL to set + */ + public void setURL(String url) { + this.url = url; + } + + /** + * Sets the vertical offset for images. + * @param vertical The vertical offset to set + */ + public void setVertical(int vertical) { + this.vertical = vertical; + } + + } + +} + diff --git a/src/java/org/apache/fop/area/TreeExt.java b/src/java/org/apache/fop/area/TreeExt.java new file mode 100644 index 000000000..4e1b77182 --- /dev/null +++ b/src/java/org/apache/fop/area/TreeExt.java @@ -0,0 +1,103 @@ +/* + * $Id: TreeExt.java,v 1.4 2003/03/05 15:19:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area; + +/** + * Area tree extension interface. + * This interface is used by area tree extensions that are handled + * by the renderer. + * When this extension is handled by the area tree it is rendered + * according to the three possibilities, IMMEDIATELY, AFTER_PAGE + * or END_OF_DOC. + */ +public interface TreeExt { + /** + * Render this extension immediately when + * being handled by the area tree. + */ + public static final int IMMEDIATELY = 0; + + /** + * Render this extension after the next page is rendered + * or prepared when being handled by the area tree. + */ + public static final int AFTER_PAGE = 1; + + /** + * Render this extension at the end of the document once + * all pages have been fully rendered. + */ + public static final int END_OF_DOC = 2; + + /** + * Check if this tree extension is also resolveable so that + * the area tree can do id reference resolution when the + * extension is added to the area tree. + * + * @return true if this also implements resolveable + */ + boolean isResolveable(); + + /** + * Get the mime type for the document that this area tree + * extension applies. + * + * @return the mime type of the document where this applies + */ + String getMimeType(); + + /** + * Get the name of this extension. + * + * @return the name of this extension + */ + String getName(); +} diff --git a/src/java/org/apache/fop/area/inline/Anchor.java b/src/java/org/apache/fop/area/inline/Anchor.java new file mode 100644 index 000000000..80c0037a5 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Anchor.java @@ -0,0 +1,63 @@ +/* + * $Id: Anchor.java,v 1.4 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +/** + * Anchor area for footnote or float. + * Not sure if this is needed. + */ +public class Anchor extends InlineArea { + + // has a keep with adjacent area + // has reference to associated footnote or float out-of-line area + +} + diff --git a/src/java/org/apache/fop/area/inline/Character.java b/src/java/org/apache/fop/area/inline/Character.java new file mode 100644 index 000000000..2135162e6 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Character.java @@ -0,0 +1,89 @@ +/* + * $Id: Character.java,v 1.4 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.render.Renderer; + +/** + * Single character inline area. + * This inline area holds a single character. + */ +public class Character extends InlineArea { + private char character; + + /** + * Create a new characater inline area with the given character. + * + * @param ch the character for this inline area + */ + public Character(char ch) { + character = ch; + } + + /** + * Render this inline area. + * + * @param renderer the renderer to render this character area + */ + public void render(Renderer renderer) { + renderer.renderCharacter(this); + } + + /** + * Get the character for this inline character area. + * + * @return the character + */ + public char getChar() { + return character; + } +} + diff --git a/src/java/org/apache/fop/area/inline/Container.java b/src/java/org/apache/fop/area/inline/Container.java new file mode 100644 index 000000000..e7577182b --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Container.java @@ -0,0 +1,109 @@ +/* + * $Id: Container.java,v 1.7 2003/03/05 16:45:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; + +import java.util.List; +import java.util.ArrayList; + +/** + * Container area for inline container. + * This area should be placed in a viewport as a result of the + * inline container formatting object. + * This allows an inline area to have blocks as children. + */ +public class Container extends Area { + /** + * The list of block areas stacked inside this container + */ + protected List blocks = new ArrayList(); + + /** + * The width of this container + */ + protected int width; + + /** + * Create a new container area + */ + public Container() { + } + + /** + * Add the block to this area. + * + * @param block the block area to add + */ + public void addBlock(Block block) { + blocks.add(block); + } + + /** + * Get the block areas stacked inside this container area. + * + * @return the list of block areas + */ + public List getBlocks() { + return blocks; + } + + /** + * Get the width of this container area. + * + * @return the width + */ + public int getWidth() { + return width; + } +} + diff --git a/src/java/org/apache/fop/area/inline/FilledArea.java b/src/java/org/apache/fop/area/inline/FilledArea.java new file mode 100644 index 000000000..b4141a29f --- /dev/null +++ b/src/java/org/apache/fop/area/inline/FilledArea.java @@ -0,0 +1,100 @@ +/* + * $Id: FilledArea.java,v 1.5 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import java.util.List; +import java.util.ArrayList; + +/** + * Filled area. + * This inline area contains some inline areas. + * When the renderer gets the child areas to render + * the inline areas are repeated to fill the ipd of + * this inline parent. + * This extends InlineParent so that the renderer will render + * this as a normal inline parent. + */ +public class FilledArea extends InlineParent { + private int unitWidth; + + /** + * Create a new filled area. + */ + public FilledArea() { + } + + /** + * Set the unit width for the areas to fill the full width. + * + * @param w the unit width + */ + public void setUnitWidth(int w) { + unitWidth = w; + } + + /** + * Get the child areas for this filed area. + * This copies the references of the inline areas so that + * it fills the total width of the area a whole number of times + * for the unit width. + * + * @return the list of child areas copied to fill the width + */ + public List getChildAreas() { + int units = (int)(getWidth() / unitWidth); + List newList = new ArrayList(); + for (int count = 0; count < units; count++) { + newList.addAll(inlines); + } + return newList; + } +} + diff --git a/src/java/org/apache/fop/area/inline/ForeignObject.java b/src/java/org/apache/fop/area/inline/ForeignObject.java new file mode 100644 index 000000000..f9195d6cb --- /dev/null +++ b/src/java/org/apache/fop/area/inline/ForeignObject.java @@ -0,0 +1,96 @@ +/* + * $Id: ForeignObject.java,v 1.4 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; + +import org.w3c.dom.Document; + +// cacheable object +/** + * Foreign object inline area. + * This inline area represents an instream-foreign object. + * This holds an xml document and the associated namespace. + */ +public class ForeignObject extends Area { + private Document doc; + private String namespace; + + /** + * Create a new foreign object with the given dom and namespace. + * + * @param d the xml document + * @param ns the namespace of the document + */ + public ForeignObject(Document d, String ns) { + doc = d; + namespace = ns; + } + + /** + * Get the document for this foreign object. + * + * @return the xml document + */ + public Document getDocument() { + return doc; + } + + /** + * Get the namespace of this foreign object. + * + * @return the namespace of this document + */ + public String getNameSpace() { + return namespace; + } +} + diff --git a/src/java/org/apache/fop/area/inline/Image.java b/src/java/org/apache/fop/area/inline/Image.java new file mode 100644 index 000000000..5b9399618 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Image.java @@ -0,0 +1,82 @@ +/* + * $Id: Image.java,v 1.6 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; + +/** + * Image area for external-graphic. + * This area holds information for rendering an image. + * The url of the image is used as a key to reference the image cache. + */ +public class Image extends Area { + private String url; + + /** + * Create a new image with the given url. + * + * @param u the url of the image + */ + public Image(String u) { + url = u; + } + + /** + * Get the url of this image. + * This url is used as a key to locate the actual image data. + * + * @return the url of this image + */ + public String getURL() { + return url; + } +} + diff --git a/src/java/org/apache/fop/area/inline/InlineArea.java b/src/java/org/apache/fop/area/inline/InlineArea.java new file mode 100644 index 000000000..572f69b3c --- /dev/null +++ b/src/java/org/apache/fop/area/inline/InlineArea.java @@ -0,0 +1,205 @@ +/* + * $Id: InlineArea.java,v 1.15 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Trait; +import org.apache.fop.render.Renderer; +import org.apache.fop.traits.BorderProps; + +/** + * Inline Area + * This area is for all inline areas that can be placed + * in a line area. + * Extensions of this class should render themselves with the + * requested renderer. + */ +public class InlineArea extends Area { + // int width; + private int height; + /** + * The content ipd of this inline area + */ + protected int contentIPD = 0; + + /** + * offset position from top of parent area + */ + protected int verticalPosition = 0; + + /** + * Render this inline area. + * Inline areas that extend this class are expected + * to implement this method to render themselves in + * the renderer. + * + * @param renderer the renderer to render this inline area + */ + public void render(Renderer renderer) { + } + + /** + * Set the width of this inline area. + * Currently sets the ipd. + * + * @param w the width + */ + public void setWidth(int w) { + contentIPD = w; + } + + /** + * Get the width of this inline area. + * Currently gets the ipd. + * + * @return the width + */ + public int getWidth() { + return contentIPD; + } + + /** + * Set the inline progression dimension of this inline area. + * + * @param ipd the inline progression dimension + */ + public void setIPD(int ipd) { + this.contentIPD = ipd; + } + + /** + * Get the inline progression dimension + * + * @return the inline progression dimension of this area + */ + public int getIPD() { + return this.contentIPD; + } + + /** + * Increase the inline progression dimensions of this area. + * This is used for inline parent areas that contain mulitple child areas. + * + * @param ipd the inline progression to increase by + */ + public void increaseIPD(int ipd) { + this.contentIPD += ipd; + } + + /** + * Set the height of this inline area. + * + * @param h the height value to set + */ + public void setHeight(int h) { + height = h; + } + + /** + * Get the height of this inline area. + * + * @return the height of the inline area + */ + public int getHeight() { + return height; + } + + /** + * Get the allocation inline progression dimension of this area. + * This adds the content, borders and the padding to find the + * total allocated IPD. + * + * @return the total IPD allocation for this area + */ + public int getAllocIPD() { + // If start or end border or padding is non-zero, add to content IPD + int iBP = contentIPD; + Object t; + if ((t = getTrait(Trait.PADDING_START)) != null) { + iBP += ((Integer) t).intValue(); + } + if ((t = getTrait(Trait.PADDING_END)) != null) { + iBP += ((Integer) t).intValue(); + } + if ((t = getTrait(Trait.BORDER_START)) != null) { + iBP += ((BorderProps) t).width; + } + if ((t = getTrait(Trait.BORDER_END)) != null) { + iBP += ((BorderProps) t).width; + } + return iBP; + } + + /** + * Set the offset of this inline area. + * This is used to set the offset of the inline area + * which is normally relative to the top of the line + * or the baseline. + * + * @param v the offset + */ + public void setOffset(int v) { + verticalPosition = v; + } + + /** + * Get the offset of this inline area. + * This returns the offset of the inline area + * which is normally relative to the top of the line + * or the baseline. + * + * @return the offset + */ + public int getOffset() { + return verticalPosition; + } +} + diff --git a/src/java/org/apache/fop/area/inline/InlineParent.java b/src/java/org/apache/fop/area/inline/InlineParent.java new file mode 100644 index 000000000..8b79f15cb --- /dev/null +++ b/src/java/org/apache/fop/area/inline/InlineParent.java @@ -0,0 +1,111 @@ +/* + * $Id: InlineParent.java,v 1.9 2003/03/05 16:45:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; +import org.apache.fop.render.Renderer; + +import java.util.List; +import java.util.ArrayList; + +/** + * Inline parent area. + * This is an inline area that can have other inlines as children. + */ +public class InlineParent extends InlineArea { + /** + * The list of inline areas added to this inline parent. + */ + protected List inlines = new ArrayList(); + + /** + * An inline parent is a reference area somay have clipping + */ + protected boolean clip = false; + + /** + * Create a new inline parent to add areas to. + */ + public InlineParent() { + } + + /** + * Render this area. + * + * @param renderer the renderer to render this area in + */ + public void render(Renderer renderer) { + renderer.renderInlineParent(this); + } + + /** + * Override generic Area method. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + if (childArea instanceof InlineArea) { + inlines.add(childArea); + increaseIPD(((InlineArea) childArea).getAllocIPD()); + } + } + + /** + * Get the child areas for this inline parent. + * + * @return the list of child areas + */ + public List getChildAreas() { + return inlines; + } + +} + diff --git a/src/java/org/apache/fop/area/inline/Leader.java b/src/java/org/apache/fop/area/inline/Leader.java new file mode 100644 index 000000000..6f045510b --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Leader.java @@ -0,0 +1,121 @@ +/* + * $Id: Leader.java,v 1.6 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.render.Renderer; +import org.apache.fop.fo.properties.RuleStyle; + +/** + * This is a leader inline area. + * This class is only used for leader with leader-pattern of rule. + */ +public class Leader extends InlineArea { + + // in the case of use content or dots this is replaced + // with the set of inline areas + // if space replaced with a space + // otherwise this is a holder for a line + + private int ruleStyle = RuleStyle.SOLID; + private int ruleThickness = 1000; + + /** + * Create a new leader area. + */ + public Leader() { + } + + /** + * Set the rule style of this leader area. + * + * @param style the rule style for the leader line + */ + public void setRuleStyle(int style) { + ruleStyle = style; + } + + /** + * Set the rule thickness of the rule in miilipoints. + * + * @param rt the rule thickness in millipoints + */ + public void setRuleThickness(int rt) { + ruleThickness = rt; + } + + /** + * Get the rule style of this leader. + * + * @return the rule style + */ + public int getRuleStyle() { + return ruleStyle; + } + + /** + * Get the rule thickness of the rule in miilipoints. + * + * @return the rule thickness in millipoints + */ + public int getRuleThickness() { + return ruleThickness; + } + + /** + * Render this leader in the current renderer. + * + * @param renderer the renderer to render this inline area + */ + public void render(Renderer renderer) { + renderer.renderLeader(this); + } +} + diff --git a/src/java/org/apache/fop/area/inline/Space.java b/src/java/org/apache/fop/area/inline/Space.java new file mode 100644 index 000000000..a4391d6af --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Space.java @@ -0,0 +1,69 @@ +/* + * $Id: Space.java,v 1.5 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.render.Renderer; + +/** + * Inline space area. + * This is used for adding a inline space to the output. + */ +public class Space extends InlineArea { + + /** + * Render this inlien space area. + * + * @param renderer the renderer to render this inline area + */ + public void render(Renderer renderer) { + renderer.renderInlineSpace(this); + } +} diff --git a/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java new file mode 100644 index 000000000..0a46d87b1 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java @@ -0,0 +1,115 @@ +/* + * $Id: UnresolvedPageNumber.java,v 1.7 2003/03/05 16:45:43 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Resolveable; + +import java.util.List; + +/** + * Unresolveable page number area. + * This is a word area that resolves itself to a page number + * from an id reference. + */ +public class UnresolvedPageNumber extends Word implements Resolveable { + private boolean resolved = false; + private String pageRefId; + + /** + * Create a new unresolveable page number. + * + * @param id the id reference for resolving this + */ + public UnresolvedPageNumber(String id) { + pageRefId = id; + word = "?"; + } + + /** + * Get the id references for this area. + * + * @return the id reference for this unresolved page number + */ + public String[] getIDs() { + return new String[] {pageRefId}; + } + + /** + * Resolve this page number reference. + * This resolves the reference by getting the page number + * string from the first page in the list of pages that apply + * for the id reference. The word string is then set to the + * page number string. + * + * @param id the id reference being resolved + * @param pages the list of pages for the id reference + */ + public void resolve(String id, List pages) { + resolved = true; + if (pages != null) { + PageViewport page = (PageViewport)pages.get(0); + String str = page.getPageNumber(); + word = str; + + /**@todo Update IPD ??? */ + } + } + + /** + * Check if this is resolved. + * + * @return true when this has been resolved + */ + public boolean isResolved() { + return resolved; + } +} diff --git a/src/java/org/apache/fop/area/inline/Viewport.java b/src/java/org/apache/fop/area/inline/Viewport.java new file mode 100644 index 000000000..e9a736d4b --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Viewport.java @@ -0,0 +1,164 @@ +/* + * $Id: Viewport.java,v 1.7 2003/03/05 16:45:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.area.Area; +import org.apache.fop.render.Renderer; + +import java.io.IOException; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; + +/** + * Inline viewport area. + * This is an inline-level viewport area for inline container, + * external graphic and instream foreign object. This viewport + * holds the area and positions it. + */ +public class Viewport extends InlineArea { + // contents could be container, foreign object or image + private Area content; + // clipping for the viewport + private boolean clip = false; + // position of the cild area relative to this area + private Rectangle2D contentPosition; + + /** + * Create a new viewport area with the content area. + * + * @param child the child content area of this viewport + */ + public Viewport(Area child) { + content = child; + } + + /** + * Set the clip of this viewport. + * + * @param c true if this viewport should clip + */ + public void setClip(boolean c) { + clip = c; + } + + /** + * Get the clip of this viewport. + * + * @return true if this viewport should clip + */ + public boolean getClip() { + return clip; + } + + /** + * Set the position and size of the content of this viewport. + * + * @param cp the position and size to place the content + */ + public void setContentPosition(Rectangle2D cp) { + contentPosition = cp; + } + + /** + * Get the position and size of the content of this viewport. + * + * @return the position and size to place the content + */ + public Rectangle2D getContentPosition() { + return contentPosition; + } + + /** + * Get the content area for this viewport. + * + * @return the content area + */ + public Area getContent() { + return content; + } + + /** + * Render this inline area. + * + * @param renderer the renderer to render this inline area + */ + public void render(Renderer renderer) { + renderer.renderViewport(this); + } + + private void writeObject(java.io.ObjectOutputStream out) + throws IOException { + out.writeBoolean(contentPosition != null); + if (contentPosition != null) { + out.writeFloat((float) contentPosition.getX()); + out.writeFloat((float) contentPosition.getY()); + out.writeFloat((float) contentPosition.getWidth()); + out.writeFloat((float) contentPosition.getHeight()); + } + out.writeBoolean(clip); + out.writeObject(props); + out.writeObject(content); + } + + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException { + if (in.readBoolean()) { + contentPosition = new Rectangle2D.Float(in.readFloat(), + in.readFloat(), + in.readFloat(), + in.readFloat()); + } + clip = in.readBoolean(); + props = (HashMap) in.readObject(); + content = (Area) in.readObject(); + } + +} diff --git a/src/java/org/apache/fop/area/inline/Word.java b/src/java/org/apache/fop/area/inline/Word.java new file mode 100644 index 000000000..2977c3310 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/Word.java @@ -0,0 +1,118 @@ +/* + * $Id: Word.java,v 1.10 2003/03/05 16:45:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.area.inline; + +import org.apache.fop.render.Renderer; + +/** + * A word inline area. + * This is really a collection character inline areas collected together + * into a single word. + */ +public class Word extends InlineArea { + /** + * The word for this word area. + */ + protected String word; + private int iWSadjust = 0; + + /** + * Create a word area. + */ + public Word() { + } + + /** + * Render the word to the renderer. + * + * @param renderer the renderer to render this word + */ + public void render(Renderer renderer) { + renderer.renderWord(this); + } + + /** + * Set the word. + * + * @param w the word string + */ + public void setWord(String w) { + word = w; + } + + /** + * Get the word string. + * + * @return the word string + */ + public String getWord() { + return word; + } + + /** + * Get word space adjust. + * + * @return the word space adjustment + */ + public int getWSadjust() { + return iWSadjust; + } + + /** + * Set word space adjust. + * + * @param iWSadjust the word space adjustment + */ + public void setWSadjust(int iWSadjust) { + this.iWSadjust = iWSadjust; + } +} + diff --git a/src/java/org/apache/fop/datatypes/AutoLength.java b/src/java/org/apache/fop/datatypes/AutoLength.java new file mode 100644 index 000000000..d31f92303 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/AutoLength.java @@ -0,0 +1,77 @@ +/* + * $Id: AutoLength.java,v 1.3 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +/** + * A length quantity in XSL which is specified as "auto". + */ +public class AutoLength extends Length { + + /** + * @see org.apache.fop.datatypes.Length#isAuto() + */ + public boolean isAuto() { + return true; + } + + // Should we do something intelligent here to set the actual size? + // Would need a reference object! + // protected void computeValue() { + // } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return "auto"; + } + +} diff --git a/src/java/org/apache/fop/datatypes/ColorType.java b/src/java/org/apache/fop/datatypes/ColorType.java new file mode 100644 index 000000000..7b214be20 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/ColorType.java @@ -0,0 +1,741 @@ +/* + * $Id: ColorType.java,v 1.21 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import java.io.Serializable; +import java.util.StringTokenizer; + +/** + * A colour quantity in XSL. + */ +public class ColorType implements Serializable { + + /** + * the red component + */ + protected float red; + + /** + * the green component + */ + protected float green; + + /** + * the blue component + */ + protected float blue; + + /** + * the alpha component + */ + protected float alpha = 0; + + /** + * Main constructor + * @param red red component + * @param green green component + * @param blue blue component + */ + public ColorType(float red, float green, float blue) { + this.red = red; + this.green = green; + this.blue = blue; + } + + /** + * Set the colour given a particular String specifying either a + * colour name or #RGB or #RRGGBB + * @param value RGB value as String to be parsed + */ + public ColorType(String value) { + if (value.startsWith("#")) { + try { + if (value.length() == 4) { + // note: divide by 15 so F = FF = 1 and so on + this.red = Integer.parseInt(value.substring(1, 2), 16) + / 15f; + this.green = Integer.parseInt(value.substring(2, 3), 16) + / 15f; + this.blue = Integer.parseInt(value.substring(3), 16) + / 15f; + } else if (value.length() == 7) { + // note: divide by 255 so FF = 1 + this.red = Integer.parseInt(value.substring(1, 3), 16) + / 255f; + this.green = Integer.parseInt(value.substring(3, 5), 16) + / 255f; + this.blue = Integer.parseInt(value.substring(5), 16) + / 255f; + } else { + this.red = 0; + this.green = 0; + this.blue = 0; + //log.error("unknown colour format. Must be #RGB or #RRGGBB"); + } + } catch (Exception e) { + this.red = 0; + this.green = 0; + this.blue = 0; + //log.error("unknown colour format. Must be #RGB or #RRGGBB"); + } + } else if (value.startsWith("rgb(")) { + int poss = value.indexOf("("); + int pose = value.indexOf(")"); + if (poss != -1 && pose != -1) { + value = value.substring(poss + 1, pose); + StringTokenizer st = new StringTokenizer(value, ","); + try { + if (st.hasMoreTokens()) { + String str = st.nextToken().trim(); + if (str.endsWith("%")) { + this.red = + Integer.parseInt(str.substring(0, str.length() - 1)) + * 2.55f; + } else { + this.red = Integer.parseInt(str) / 255f; + } + } + if (st.hasMoreTokens()) { + String str = st.nextToken().trim(); + if (str.endsWith("%")) { + this.green = + Integer.parseInt(str.substring(0, str.length() - 1)) + * 2.55f; + } else { + this.green = Integer.parseInt(str) / 255f; + } + } + if (st.hasMoreTokens()) { + String str = st.nextToken().trim(); + if (str.endsWith("%")) { + this.blue = + Integer.parseInt(str.substring(0, str.length() - 1)) + * 2.55f; + } else { + this.blue = Integer.parseInt(str) / 255f; + } + } + } catch (Exception e) { + this.red = 0; + this.green = 0; + this.blue = 0; + //log.error("unknown colour format. Must be #RGB or #RRGGBB"); + } + } + } else if (value.startsWith("url(")) { + // refers to a gradient + } else { + if (value.toLowerCase().equals("transparent")) { + this.red = 0; + this.green = 0; + this.blue = 0; + this.alpha = 1; + } else { + boolean found = false; + for (int count = 0; count < NAMES.length; count++) { + if (value.toLowerCase().equals(NAMES[count])) { + this.red = VALUES[count][0] / 255f; + this.green = VALUES[count][1] / 255f; + this.blue = VALUES[count][2] / 255f; + found = true; + break; + } + } + if (!found) { + this.red = 0; + this.green = 0; + this.blue = 0; + //log.error("unknown colour name: " + // + value); + } + } + } + } + + /** + * Returns the blue component of the color. + * @return float a value between 0.0 and 1.0 + */ + public float getBlue() { + return this.blue; + } + + /** + * Returns the green component of the color. + * @return float a value between 0.0 and 1.0 + */ + public float getGreen() { + return this.green; + } + + /** + * Returns the red component of the color. + * @return float a value between 0.0 and 1.0 + */ + public float getRed() { + return this.red; + } + + /** + * Returns the alpha (transparency) component of the color. + * @return float a value between 0.0 and 1.0 + */ + public float alpha() { + return this.alpha; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sbuf = new StringBuffer(8); + sbuf.append('#'); + String s = Integer.toHexString((int)(red * 255.0)); + if (s.length() == 1) { + sbuf.append('0'); + } + sbuf.append(s); + s = Integer.toHexString((int)(green * 255.0)); + if (s.length() == 1) { + sbuf.append('0'); + } + sbuf.append(s); + s = Integer.toHexString((int)(blue * 255.0)); + if (s.length() == 1) { + sbuf.append('0'); + } + sbuf.append(s); + return sbuf.toString(); + } + + /** The names of the predefined colors */ + protected static final String[] NAMES = { + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", + "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", + "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", + "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", + "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", + "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", + "darkorchid", "darkred", "darksalmon", "darkseagreen", + "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", + "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", + "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", + "gainsboro", "lightpink", "lightsalmon", "lightseagreen", + "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", + "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", + "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", + "mediumseagreen", "mediumslateblue", "mediumspringgreen", + "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", + "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", + "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", + "palegreen", "paleturquoise", "palevioletred", "papayawhip", + "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "red", + "rosybrown", "royalblue", "saddlebrown", "salmon", "ghostwhite", + "gold", "goldenrod", "gray", "grey", "green", "greenyellow", + "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", + "lavender", "lavenderblush", "lawngreen", "lemonchiffon", + "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", + "lightgray", "lightgreen", "lightgrey", "sandybrown", "seagreen", + "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", + "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", + "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen" + }; + + /** The color values for the predefined colors */ + protected static final int[][] VALUES = { + { + 240, 248, 255 + }, { + 250, 235, 215 + }, { + 0, 255, 255 + }, { + 127, 255, 212 + }, { + 240, 255, 255 + }, { + 245, 245, 220 + }, { + 255, 228, 196 + }, { + 0, 0, 0 + }, { + 255, 235, 205 + }, { + 0, 0, 255 + }, { + 138, 43, 226 + }, { + 165, 42, 42 + }, { + 222, 184, 135 + }, { + 95, 158, 160 + }, { + 127, 255, 0 + }, { + 210, 105, 30 + }, { + 255, 127, 80 + }, { + 100, 149, 237 + }, { + 255, 248, 220 + }, { + 220, 20, 60 + }, { + 0, 255, 255 + }, { + 0, 0, 139 + }, { + 0, 139, 139 + }, { + 184, 134, 11 + }, { + 169, 169, 169 + }, { + 0, 100, 0 + }, { + 169, 169, 169 + }, { + 189, 183, 107 + }, { + 139, 0, 139 + }, { + 85, 107, 47 + }, { + 255, 140, 0 + }, { + 153, 50, 204 + }, { + 139, 0, 0 + }, { + 233, 150, 122 + }, { + 143, 188, 143 + }, { + 72, 61, 139 + }, { + 47, 79, 79 + }, { + 47, 79, 79 + }, { + 0, 206, 209 + }, { + 148, 0, 211 + }, { + 255, 20, 147 + }, { + 0, 191, 255 + }, { + 105, 105, 105 + }, { + 105, 105, 105 + }, { + 30, 144, 255 + }, { + 178, 34, 34 + }, { + 255, 250, 240 + }, { + 34, 139, 34 + }, { + 255, 0, 255 + }, { + 220, 220, 220 + }, { + 255, 182, 193 + }, { + 255, 160, 122 + }, { + 32, 178, 170 + }, { + 135, 206, 250 + }, { + 119, 136, 153 + }, { + 119, 136, 153 + }, { + 176, 196, 222 + }, { + 255, 255, 224 + }, { + 0, 255, 0 + }, { + 50, 205, 50 + }, { + 250, 240, 230 + }, { + 255, 0, 255 + }, { + 128, 0, 0 + }, { + 102, 205, 170 + }, { + 0, 0, 205 + }, { + 186, 85, 211 + }, { + 147, 112, 219 + }, { + 60, 179, 113 + }, { + 123, 104, 238 + }, { + 0, 250, 154 + }, { + 72, 209, 204 + }, { + 199, 21, 133 + }, { + 25, 25, 112 + }, { + 245, 255, 250 + }, { + 255, 228, 225 + }, { + 255, 228, 181 + }, { + 255, 222, 173 + }, { + 0, 0, 128 + }, { + 253, 245, 230 + }, { + 128, 128, 0 + }, { + 107, 142, 35 + }, { + 255, 165, 0 + }, { + 255, 69, 0 + }, { + 218, 112, 214 + }, { + 238, 232, 170 + }, { + 152, 251, 152 + }, { + 175, 238, 238 + }, { + 219, 112, 147 + }, { + 255, 239, 213 + }, { + 255, 218, 185 + }, { + 205, 133, 63 + }, { + 255, 192, 203 + }, { + 221, 160, 221 + }, { + 176, 224, 230 + }, { + 128, 0, 128 + }, { + 255, 0, 0 + }, { + 188, 143, 143 + }, { + 65, 105, 225 + }, { + 139, 69, 19 + }, { + 250, 128, 114 + }, { + 248, 248, 255 + }, { + 255, 215, 0 + }, { + 218, 165, 32 + }, { + 128, 128, 128 + }, { + 128, 128, 128 + }, { + 0, 128, 0 + }, { + 173, 255, 47 + }, { + 240, 255, 240 + }, { + 255, 105, 180 + }, { + 205, 92, 92 + }, { + 75, 0, 130 + }, { + 255, 255, 240 + }, { + 240, 230, 140 + }, { + 230, 230, 250 + }, { + 255, 240, 245 + }, { + 124, 252, 0 + }, { + 255, 250, 205 + }, { + 173, 216, 230 + }, { + 240, 128, 128 + }, { + 224, 255, 255 + }, { + 250, 250, 210 + }, { + 211, 211, 211 + }, { + 144, 238, 144 + }, { + 211, 211, 211 + }, { + 244, 164, 96 + }, { + 46, 139, 87 + }, { + 255, 245, 238 + }, { + 160, 82, 45 + }, { + 192, 192, 192 + }, { + 135, 206, 235 + }, { + 106, 90, 205 + }, { + 112, 128, 144 + }, { + 112, 128, 144 + }, { + 255, 250, 250 + }, { + 0, 255, 127 + }, { + 70, 130, 180 + }, { + 210, 180, 140 + }, { + 0, 128, 128 + }, { + 216, 191, 216 + }, { + 255, 99, 71 + }, { + 64, 224, 208 + }, { + 238, 130, 238 + }, { + 245, 222, 179 + }, { + 255, 255, 255 + }, { + 245, 245, 245 + }, { + 255, 255, 0 + }, { + 154, 205, 50 + } + }; +} + +/* + * aliceblue rgb(240, 248, 255) + * antiquewhite rgb(250, 235, 215) + * aqua rgb( 0, 255, 255) + * aquamarine rgb(127, 255, 212) + * azure rgb(240, 255, 255) + * beige rgb(245, 245, 220) + * bisque rgb(255, 228, 196) + * black rgb( 0, 0, 0) + * blanchedalmond rgb(255, 235, 205) + * blue rgb( 0, 0, 255) + * blueviolet rgb(138, 43, 226) + * brown rgb(165, 42, 42) + * burlywood rgb(222, 184, 135) + * cadetblue rgb( 95, 158, 160) + * chartreuse rgb(127, 255, 0) + * chocolate rgb(210, 105, 30) + * coral rgb(255, 127, 80) + * cornflowerblue rgb(100, 149, 237) + * cornsilk rgb(255, 248, 220) + * crimson rgb(220, 20, 60) + * cyan rgb( 0, 255, 255) + * darkblue rgb( 0, 0, 139) + * darkcyan rgb( 0, 139, 139) + * darkgoldenrod rgb(184, 134, 11) + * darkgray rgb(169, 169, 169) + * darkgreen rgb( 0, 100, 0) + * darkgrey rgb(169, 169, 169) + * darkkhaki rgb(189, 183, 107) + * darkmagenta rgb(139, 0, 139) + * darkolivegreen rgb( 85, 107, 47) + * darkorange rgb(255, 140, 0) + * darkorchid rgb(153, 50, 204) + * darkred rgb(139, 0, 0) + * darksalmon rgb(233, 150, 122) + * darkseagreen rgb(143, 188, 143) + * darkslateblue rgb( 72, 61, 139) + * darkslategray rgb( 47, 79, 79) + * darkslategrey rgb( 47, 79, 79) + * darkturquoise rgb( 0, 206, 209) + * darkviolet rgb(148, 0, 211) + * deeppink rgb(255, 20, 147) + * deepskyblue rgb( 0, 191, 255) + * dimgray rgb(105, 105, 105) + * dimgrey rgb(105, 105, 105) + * dodgerblue rgb( 30, 144, 255) + * firebrick rgb(178, 34, 34) + * floralwhite rgb(255, 250, 240) + * forestgreen rgb( 34, 139, 34) + * fuchsia rgb(255, 0, 255) + * gainsboro rgb(220, 220, 220) + * lightpink rgb(255, 182, 193) + * lightsalmon rgb(255, 160, 122) + * lightseagreen rgb( 32, 178, 170) + * lightskyblue rgb(135, 206, 250) + * lightslategray rgb(119, 136, 153) + * lightslategrey rgb(119, 136, 153) + * lightsteelblue rgb(176, 196, 222) + * lightyellow rgb(255, 255, 224) + * lime rgb( 0, 255, 0) + * limegreen rgb( 50, 205, 50) + * linen rgb(250, 240, 230) + * magenta rgb(255, 0, 255) + * maroon rgb(128, 0, 0) + * mediumaquamarine rgb(102, 205, 170) + * mediumblue rgb( 0, 0, 205) + * mediumorchid rgb(186, 85, 211) + * mediumpurple rgb(147, 112, 219) + * mediumseagreen rgb( 60, 179, 113) + * mediumslateblue rgb(123, 104, 238) + * mediumspringgreen rgb( 0, 250, 154) + * mediumturquoise rgb( 72, 209, 204) + * mediumvioletred rgb(199, 21, 133) + * midnightblue rgb( 25, 25, 112) + * mintcream rgb(245, 255, 250) + * mistyrose rgb(255, 228, 225) + * moccasin rgb(255, 228, 181) + * navajowhite rgb(255, 222, 173) + * navy rgb( 0, 0, 128) + * oldlace rgb(253, 245, 230) + * olive rgb(128, 128, 0) + * olivedrab rgb(107, 142, 35) + * orange rgb(255, 165, 0) + * orangered rgb(255, 69, 0) + * orchid rgb(218, 112, 214) + * palegoldenrod rgb(238, 232, 170) + * palegreen rgb(152, 251, 152) + * paleturquoise rgb(175, 238, 238) + * palevioletred rgb(219, 112, 147) + * papayawhip rgb(255, 239, 213) + * peachpuff rgb(255, 218, 185) + * peru rgb(205, 133, 63) + * pink rgb(255, 192, 203) + * plum rgb(221, 160, 221) + * powderblue rgb(176, 224, 230) + * purple rgb(128, 0, 128) + * red rgb(255, 0, 0) + * rosybrown rgb(188, 143, 143) + * royalblue rgb( 65, 105, 225) + * saddlebrown rgb(139, 69, 19) + * salmon rgb(250, 128, 114) + * ghostwhite rgb(248, 248, 255) + * gold rgb(255, 215, 0) + * goldenrod rgb(218, 165, 32) + * gray rgb(128, 128, 128) + * grey rgb(128, 128, 128) + * green rgb( 0, 128, 0) + * greenyellow rgb(173, 255, 47) + * honeydew rgb(240, 255, 240) + * hotpink rgb(255, 105, 180) + * indianred rgb(205, 92, 92) + * indigo rgb( 75, 0, 130) + * ivory rgb(255, 255, 240) + * khaki rgb(240, 230, 140) + * lavender rgb(230, 230, 250) + * lavenderblush rgb(255, 240, 245) + * lawngreen rgb(124, 252, 0) + * lemonchiffon rgb(255, 250, 205) + * lightblue rgb(173, 216, 230) + * lightcoral rgb(240, 128, 128) + * lightcyan rgb(224, 255, 255) + * lightgoldenrodyellow rgb(250, 250, 210) + * lightgray rgb(211, 211, 211) + * lightgreen rgb(144, 238, 144) + * lightgrey rgb(211, 211, 211) + * sandybrown rgb(244, 164, 96) + * seagreen rgb( 46, 139, 87) + * seashell rgb(255, 245, 238) + * sienna rgb(160, 82, 45) + * silver rgb(192, 192, 192) + * skyblue rgb(135, 206, 235) + * slateblue rgb(106, 90, 205) + * slategray rgb(112, 128, 144) + * slategrey rgb(112, 128, 144) + * snow rgb(255, 250, 250) + * springgreen rgb( 0, 255, 127) + * steelblue rgb( 70, 130, 180) + * tan rgb(210, 180, 140) + * teal rgb( 0, 128, 128) + * thistle rgb(216, 191, 216) + * tomato rgb(255, 99, 71) + * turquoise rgb( 64, 224, 208) + * violet rgb(238, 130, 238) + * wheat rgb(245, 222, 179) + * white rgb(255, 255, 255) + * whitesmoke rgb(245, 245, 245) + * yellow rgb(255, 255, 0) + * yellowgreen rgb(154, 205, 50) + */ diff --git a/src/java/org/apache/fop/datatypes/CompoundDatatype.java b/src/java/org/apache/fop/datatypes/CompoundDatatype.java new file mode 100644 index 000000000..137911497 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/CompoundDatatype.java @@ -0,0 +1,74 @@ +/* + * $Id: CompoundDatatype.java,v 1.3 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; + +/** + * This interface is used as a base for compound datatypes. + */ +public interface CompoundDatatype { + + /** + * Sets a component of the compound datatype. + * @param sCmpnName name of the component + * @param cmpnValue value of the component + * @param bIsDefault Indicates if it's the default value + */ + void setComponent(String sCmpnName, Property cmpnValue, boolean bIsDefault); + + /** + * Returns a component of the compound datatype. + * @param sCmpnName name of the component + * @return the value of the component + */ + Property getComponent(String sCmpnName); +} diff --git a/src/java/org/apache/fop/datatypes/CondLength.java b/src/java/org/apache/fop/datatypes/CondLength.java new file mode 100644 index 000000000..07e817db9 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/CondLength.java @@ -0,0 +1,123 @@ +/* + * $Id: CondLength.java,v 1.7 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.properties.Constants; + +/** + * A space quantity in XSL (space-before, space-after). + * See length-conditional datatype in the specs. + */ +public class CondLength implements CompoundDatatype { + + private Property length; + private Property conditionality; + + /** + * @see org.apache.fop.datatypes.CompoundDatatype#setComponent(String, Property, boolean) + */ + public void setComponent(String sCmpnName, Property cmpnValue, + boolean bIsDefault) { + if (sCmpnName.equals("length")) { + length = cmpnValue; + } else if (sCmpnName.equals("conditionality")) { + conditionality = cmpnValue; + } + } + + /** + * @see org.apache.fop.datatypes.CompoundDatatype#getComponent(String) + */ + public Property getComponent(String sCmpnName) { + if (sCmpnName.equals("length")) { + return length; + } else if (sCmpnName.equals("conditionality")) { + return conditionality; + } else { + return null; + } + } + + /** + * Returns the conditionality. + * @return the conditionality + */ + public Property getConditionality() { + return this.conditionality; + } + + /** + * Returns the length. + * @return the length + */ + public Property getLength() { + return this.length; + } + + /** + * Indicates if the length can be discarded on certain conditions. + * @return true if the length can be discarded. + */ + public boolean isDiscard() { + return this.conditionality.getEnum() == Constants.DISCARD; + } + + /** + * Returns the computed length value. + * @return the length in millipoints + */ + public int getLengthValue() { + return this.length.getLength().getValue(); + } + +} + diff --git a/src/java/org/apache/fop/datatypes/FODimension.java b/src/java/org/apache/fop/datatypes/FODimension.java new file mode 100644 index 000000000..2a839a3b7 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/FODimension.java @@ -0,0 +1,68 @@ +/* + * $Id: FODimension.java,v 1.3 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +/** + * This datatype hold a pair of resolved lengths, + * specifiying the dimensions in + * both inline and block-progression-directions. + */ +public class FODimension { + + public int ipd; + public int bpd; + + + public FODimension(int ipd, int bpd) { + this.ipd = ipd; + this.bpd = bpd; + } +} diff --git a/src/java/org/apache/fop/datatypes/FixedLength.java b/src/java/org/apache/fop/datatypes/FixedLength.java new file mode 100644 index 000000000..9d3605538 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/FixedLength.java @@ -0,0 +1,118 @@ +/* + * $Id: FixedLength.java,v 1.4 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.expr.Numeric; + +/** + * a length quantity in XSL + */ +public class FixedLength extends Length { + + /** + * Set the length given a number of relative units and the current + * font size in base units. + */ + public FixedLength(double numRelUnits, int iCurFontSize) { + setComputedValue((int)(numRelUnits * (double)iCurFontSize)); + } + + /** + * Set the length given a number of units and a unit name. + */ + public FixedLength(double numUnits, String units) { + convert(numUnits, units); + } + + /** + * set the length as a number of base units + */ + public FixedLength(int baseUnits) { + setComputedValue(baseUnits); + } + + /** + * Convert the given length to a dimensionless integer representing + * a whole number of base units (milli-points). + */ + protected void convert(double dvalue, String unit) { + + int assumedResolution = 1; // points/pixel + + if (unit.equals("in")) { + dvalue = dvalue * 72; + } else if (unit.equals("cm")) { + dvalue = dvalue * 28.3464567; + } else if (unit.equals("mm")) { + dvalue = dvalue * 2.83464567; + } else if (unit.equals("pt")) { + dvalue = dvalue; + } else if (unit.equals("pc")) { + dvalue = dvalue * 12; + /* + * } else if (unit.equals("em")) { + * dvalue = dvalue * fontsize; + */ + } else if (unit.equals("px")) { + dvalue = dvalue * assumedResolution; + } else { + dvalue = 0; + //log.error("unknown length unit '" + unit + // + "'"); + } + setComputedValue((int)(dvalue * 1000)); + } + + public Numeric asNumeric() { + return new Numeric(this); + } +} + diff --git a/src/java/org/apache/fop/datatypes/Keep.java b/src/java/org/apache/fop/datatypes/Keep.java new file mode 100644 index 000000000..ac363ebf2 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/Keep.java @@ -0,0 +1,123 @@ +/* + * $Id: Keep.java,v 1.5 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; + +/** + * XSL FO Keep Property datatype (keep-together, etc) + */ +public class Keep implements CompoundDatatype { + private Property withinLine; + private Property withinColumn; + private Property withinPage; + + public Keep() { + } + + // From CompoundDatatype + public void setComponent(String sCmpnName, Property cmpnValue, + boolean bIsDefault) { + if (sCmpnName.equals("within-line")) { + setWithinLine(cmpnValue, bIsDefault); + } else if (sCmpnName.equals("within-column")) { + setWithinColumn(cmpnValue, bIsDefault); + } else if (sCmpnName.equals("within-page")) { + setWithinPage(cmpnValue, bIsDefault); + } + } + + // From CompoundDatatype + public Property getComponent(String sCmpnName) { + if (sCmpnName.equals("within-line")) { + return getWithinLine(); + } else if (sCmpnName.equals("within-column")) { + return getWithinColumn(); + } else if (sCmpnName.equals("within-page")) { + return getWithinPage(); + } else { + return null; + } + } + + public void setWithinLine(Property withinLine, boolean bIsDefault) { + this.withinLine = withinLine; + } + + protected void setWithinColumn(Property withinColumn, + boolean bIsDefault) { + this.withinColumn = withinColumn; + } + + public void setWithinPage(Property withinPage, boolean bIsDefault) { + this.withinPage = withinPage; + } + + public Property getWithinLine() { + return this.withinLine; + } + + public Property getWithinColumn() { + return this.withinColumn; + } + + public Property getWithinPage() { + return this.withinPage; + } + + /** + * What to do here?? There isn't really a meaningful single value. + */ + public String toString() { + return "Keep"; + } + +} diff --git a/src/java/org/apache/fop/datatypes/KeepValue.java b/src/java/org/apache/fop/datatypes/KeepValue.java new file mode 100644 index 000000000..b4f297874 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/KeepValue.java @@ -0,0 +1,81 @@ +/* + * $Id: KeepValue.java,v 1.5 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +/** + * Keep Value + * Stores the different types of keeps in a single convenient format. + */ +public class KeepValue { + public static final String KEEP_WITH_ALWAYS = "KEEP_WITH_ALWAYS"; + public static final String KEEP_WITH_AUTO = "KEEP_WITH_AUTO"; + public static final String KEEP_WITH_VALUE = "KEEP_WITH_VALUE"; + private String type = KEEP_WITH_AUTO; + private int value = 0; + + public KeepValue(String type, int val) { + this.type = type; + this.value = val; + } + + public int getValue() { + return value; + } + + public String getType() { + return type; + } + + public String toString() { + return type; + } + +} diff --git a/src/java/org/apache/fop/datatypes/Length.java b/src/java/org/apache/fop/datatypes/Length.java new file mode 100644 index 000000000..72ec29e59 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/Length.java @@ -0,0 +1,148 @@ +/* + * $Id: Length.java,v 1.17 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.expr.Numeric; + +/** + * A length quantity in XSL + */ +public class Length { + + /** Holds the length in millipoints. */ + protected int millipoints = 0; + /** Indicates if the value has been computed, or not. */ + protected boolean bIsComputed = false; + + /** + * Returns the length in 1/1000ths of a point (millipoints) + * @return the length in millipoints + */ + public int getValue() { + if (!bIsComputed) { + computeValue(); + } + return millipoints; + } + + /** + * Computes the value. + */ + protected void computeValue() { + } + + + /** + * Sets the computed value. + * @param millipoints the length in millipoints + */ + protected void setComputedValue(int millipoints) { + setComputedValue(millipoints, true); + } + + /** + * Sets the computed value. + * @param millipoints the length in millipoints + * @param bSetComputed True if the isComputed flag should be set. + */ + protected void setComputedValue(int millipoints, boolean bSetComputed) { + this.millipoints = millipoints; + this.bIsComputed = bSetComputed; + } + + /** + * Indicates if the length has the "auto" value. + * @return True if the length is set to "auto" + */ + public boolean isAuto() { + return false; + } + + /** + * Indicates if the length has been computed. + * @return True if the length has been computed + */ + public boolean isComputed() { + return this.bIsComputed; + } + + /** + * Return the number of table units which are included in this + * length specification. + * This will always be 0 unless the property specification used + * the proportional-column-width() function (only only table + * column FOs). + *

If this value is not 0, the actual value of the Length cannot + * be known without looking at all of the columns in the table to + * determine the value of a "table-unit". + * @return The number of table units which are included in this + * length specification. + */ + public double getTableUnits() { + return 0.0; + } + + public void resolveTableUnit(double dTableUnit) { + } + + public Numeric asNumeric() { + return null; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + String s = millipoints + "mpt"; + return s; + } + +} diff --git a/src/java/org/apache/fop/datatypes/LengthBase.java b/src/java/org/apache/fop/datatypes/LengthBase.java new file mode 100644 index 000000000..e6600dc82 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/LengthBase.java @@ -0,0 +1,136 @@ +/* + * $Id: LengthBase.java,v 1.9 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; + +public class LengthBase implements PercentBase { + // Standard kinds of percent-based length + public static final int CUSTOM_BASE = 0; + public static final int FONTSIZE = 1; + public static final int INH_FONTSIZE = 2; + public static final int CONTAINING_BOX = 3; + public static final int CONTAINING_REFAREA = 4; + + /** + * FO parent of the FO for which this property is to be calculated. + */ + protected /* final */ FObj parentFO; + + /** + * PropertyList for the FO where this property is calculated. + */ + private /* final */ PropertyList propertyList; + + /** + * One of the defined types of LengthBase + */ + private /* final */ int iBaseType; + + public LengthBase(FObj parentFO, PropertyList plist, int iBaseType) { + this.parentFO = parentFO; + this.propertyList = plist; + this.iBaseType = iBaseType; + } + + /** + * Accessor for parentFO object from subclasses which define + * custom kinds of LengthBase calculations. + */ + protected FObj getParentFO() { + return parentFO; + } + + /** + * Accessor for propertyList object from subclasses which define + * custom kinds of LengthBase calculations. + */ + protected PropertyList getPropertyList() { + return propertyList; + } + + public int getDimension() { + return 1; + } + + public double getBaseValue() { + return 1.0; + } + + public int getBaseLength() { + switch (iBaseType) { + case FONTSIZE: + return propertyList.get("font-size").getLength().getValue(); + case INH_FONTSIZE: + return propertyList.getInherited("font-size").getLength().getValue(); + //case CONTAINING_BOX: + // depends on property?? inline-progression vs block-progression + //return parentFO.getContentWidth(); + case CONTAINING_REFAREA: // example: start-indent, end-indent + { + //FONode fo; + //for (fo = parentFO; fo != null && !fo.generatesReferenceAreas(); + // fo = fo.getParent()); + //return (((fo != null) && (fo instanceof FObj)) ? ((FObj)fo).getContentWidth() : 0); + return 0; + } + case CUSTOM_BASE: + //log.debug("!!! LengthBase.getBaseLength() called on CUSTOM_BASE type !!!"); + return 0; + default: + //log.error("Unknown base type for LengthBase."); + return 0; + } + } + +} + diff --git a/src/java/org/apache/fop/datatypes/LengthPair.java b/src/java/org/apache/fop/datatypes/LengthPair.java new file mode 100644 index 000000000..8a95b2ade --- /dev/null +++ b/src/java/org/apache/fop/datatypes/LengthPair.java @@ -0,0 +1,95 @@ +/* + * $Id: LengthPair.java,v 1.6 2003/03/05 20:38:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; + +/** + * This datatype hold a pair of lengths, specifiying the dimensions in + * both inline and block-progression-directions. + * It is currently only used to specify border-separation in tables. + */ +public class LengthPair implements CompoundDatatype { + + private Property ipd; + private Property bpd; + + // From CompoundDatatype + public void setComponent(String sCmpnName, Property cmpnValue, + boolean bIsDefault) { + if (sCmpnName.equals("block-progression-direction")) { + bpd = cmpnValue; + } else if (sCmpnName.equals("inline-progression-direction")) { + ipd = cmpnValue; + } + } + + // From CompoundDatatype + public Property getComponent(String sCmpnName) { + if (sCmpnName.equals("block-progression-direction")) { + return getBPD(); + } else if (sCmpnName.equals("inline-progression-direction")) { + return getIPD(); + } else { + return null; // SHOULDN'T HAPPEN + } + } + + public Property getIPD() { + return this.ipd; + } + + public Property getBPD() { + return this.bpd; + } + +} + diff --git a/src/java/org/apache/fop/datatypes/LengthRange.java b/src/java/org/apache/fop/datatypes/LengthRange.java new file mode 100644 index 000000000..c91ed6172 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/LengthRange.java @@ -0,0 +1,211 @@ +/* + * $Id: LengthRange.java,v 1.10 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; + +/** + * a "progression-dimension" quantity + * ex. block-progression-dimension, inline-progression-dimension + * corresponds to the triplet min-height, height, max-height (or width) + */ +public class LengthRange implements CompoundDatatype { + + private Property minimum; + private Property optimum; + private Property maximum; + private static final int MINSET = 1; + private static final int OPTSET = 2; + private static final int MAXSET = 4; + private int bfSet = 0; // bit field + private boolean bChecked = false; + + // From CompoundDatatype + public void setComponent(String sCmpnName, Property cmpnValue, + boolean bIsDefault) { + if (sCmpnName.equals("minimum")) { + setMinimum(cmpnValue, bIsDefault); + } else if (sCmpnName.equals("optimum")) { + setOptimum(cmpnValue, bIsDefault); + } else if (sCmpnName.equals("maximum")) { + setMaximum(cmpnValue, bIsDefault); + } + } + + // From CompoundDatatype + public Property getComponent(String sCmpnName) { + if (sCmpnName.equals("minimum")) { + return getMinimum(); + } else if (sCmpnName.equals("optimum")) { + return getOptimum(); + } else if (sCmpnName.equals("maximum")) { + return getMaximum(); + } else { + return null; // SHOULDN'T HAPPEN + } + } + + /** + * Set minimum value to min. + * @param minimum A Length value specifying the minimum value for this + * LengthRange. + * @param bIsDefault If true, this is set as a "default" value + * and not a user-specified explicit value. + */ + protected void setMinimum(Property minimum, boolean bIsDefault) { + this.minimum = minimum; + if (!bIsDefault) { + bfSet |= MINSET; + } + } + + + /** + * Set maximum value to max if it is >= optimum or optimum isn't set. + * @param max A Length value specifying the maximum value for this + * @param bIsDefault If true, this is set as a "default" value + * and not a user-specified explicit value. + */ + protected void setMaximum(Property max, boolean bIsDefault) { + maximum = max; + if (!bIsDefault) { + bfSet |= MAXSET; + } + } + + + /** + * Set the optimum value. + * @param opt A Length value specifying the optimum value for this + * @param bIsDefault If true, this is set as a "default" value + * and not a user-specified explicit value. + */ + protected void setOptimum(Property opt, boolean bIsDefault) { + optimum = opt; + if (!bIsDefault) { + bfSet |= OPTSET; + } + } + + // Minimum is prioritaire, if explicit + private void checkConsistency() { + if (bChecked) { + return; + } + // Make sure max >= min + // Must also control if have any allowed enum values! + + /** + * ******************* + * if (minimum.mvalue() > maximum.mvalue()) { + * if ((bfSet&MINSET)!=0) { + * // if minimum is explicit, force max to min + * if ((bfSet&MAXSET)!=0) { + * // Warning: min>max, resetting max to min + * log.error("forcing max to min in LengthRange"); + * } + * maximum = minimum ; + * } + * else { + * minimum = maximum; // minimum was default value + * } + * } + * // Now make sure opt <= max and opt >= min + * if (optimum.mvalue() > maximum.mvalue()) { + * if ((bfSet&OPTSET)!=0) { + * if ((bfSet&MAXSET)!=0) { + * // Warning: opt > max, resetting opt to max + * log.error("forcing opt to max in LengthRange"); + * optimum = maximum ; + * } + * else { + * maximum = optimum; // maximum was default value + * } + * } + * else { + * // opt is default and max is explicit or default + * optimum = maximum ; + * } + * } + * else if (optimum.mvalue() < minimum.mvalue()) { + * if ((bfSet&MINSET)!=0) { + * // if minimum is explicit, force opt to min + * if ((bfSet&OPTSET)!=0) { + * log.error("forcing opt to min in LengthRange"); + * } + * optimum = minimum ; + * } + * else { + * minimum = optimum; // minimum was default value + * } + * } + * *******$******* + */ + bChecked = true; + } + + public Property getMinimum() { + checkConsistency(); + return this.minimum; + } + + public Property getMaximum() { + checkConsistency(); + return this.maximum; + } + + public Property getOptimum() { + checkConsistency(); + return this.optimum; + } + +} + diff --git a/src/java/org/apache/fop/datatypes/LinearCombinationLength.java b/src/java/org/apache/fop/datatypes/LinearCombinationLength.java new file mode 100644 index 000000000..65a209c07 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/LinearCombinationLength.java @@ -0,0 +1,84 @@ +/* + * $Id: LinearCombinationLength.java,v 1.4 2003/03/05 20:38:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import java.util.Vector; + +public class LinearCombinationLength extends Length { + + protected Vector factors; + protected Vector lengths; + + public LinearCombinationLength() { + factors = new Vector(); + lengths = new Vector(); + } + + public void addTerm(double factor, Length length) { + factors.addElement(new Double(factor)); + lengths.addElement(length); + } + + /** + * Return the computed value in millipoints. + */ + protected void computeValue() { + int result = 0; + int numFactors = factors.size(); + for (int i = 0; i < numFactors; ++i) { + result += + (int)(((Double)factors.elementAt(i)).doubleValue() + * (double)((Length)lengths.elementAt(i)).getValue()); + } + setComputedValue(result); + } + +} diff --git a/src/java/org/apache/fop/datatypes/MixedLength.java b/src/java/org/apache/fop/datatypes/MixedLength.java new file mode 100644 index 000000000..c653390a6 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/MixedLength.java @@ -0,0 +1,134 @@ +/* + * $Id: MixedLength.java,v 1.6 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import java.util.Vector; +import java.util.Enumeration; + +import org.apache.fop.fo.expr.Numeric; +import org.apache.fop.fo.expr.PropertyException; + +/** + * A length quantity in XSL which is specified with a mixture + * of absolute and relative and/or percent components. + * The actual value may not be computable before layout is done. + */ +public class MixedLength extends Length { + + private Vector lengths ; + + public MixedLength(Vector lengths) { + this.lengths = lengths; + } + + protected void computeValue() { + int computedValue = 0; + boolean bAllComputed = true; + Enumeration e = lengths.elements(); + while (e.hasMoreElements()) { + Length l = (Length) e.nextElement(); + computedValue += l.getValue(); + if (!l.isComputed()) { + bAllComputed = false; + } + } + setComputedValue(computedValue, bAllComputed); + } + + + public double getTableUnits() { + double tableUnits = 0.0; + Enumeration e = lengths.elements(); + while (e.hasMoreElements()) { + tableUnits += ((Length) e.nextElement()).getTableUnits(); + } + return tableUnits; + } + + public void resolveTableUnit(double dTableUnit) { + Enumeration e = lengths.elements(); + while (e.hasMoreElements()) { + ((Length) e.nextElement()).resolveTableUnit(dTableUnit); + } + } + + public String toString() { + StringBuffer sbuf = new StringBuffer(); + Enumeration e = lengths.elements(); + while (e.hasMoreElements()) { + if (sbuf.length() > 0) { + sbuf.append('+'); + } + sbuf.append(e.nextElement().toString()); + } + return sbuf.toString(); + } + + public Numeric asNumeric() { + Numeric numeric = null; + for (Enumeration e = lengths.elements(); e.hasMoreElements();) { + Length l = (Length) e.nextElement(); + if (numeric == null) { + numeric = l.asNumeric(); + } else { + try { + Numeric sum = numeric.add(l.asNumeric()); + numeric = sum; + } catch (PropertyException pe) { + System.err.println( + "Can't convert MixedLength to Numeric: " + pe); + } + } + } + return numeric; + } +} + diff --git a/src/java/org/apache/fop/datatypes/PercentBase.java b/src/java/org/apache/fop/datatypes/PercentBase.java new file mode 100644 index 000000000..4a21ffe70 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/PercentBase.java @@ -0,0 +1,57 @@ +/* + * $Id: PercentBase.java,v 1.3 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +public interface PercentBase { + int getDimension(); + double getBaseValue(); + int getBaseLength(); +} diff --git a/src/java/org/apache/fop/datatypes/PercentLength.java b/src/java/org/apache/fop/datatypes/PercentLength.java new file mode 100644 index 000000000..ccca02079 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/PercentLength.java @@ -0,0 +1,107 @@ +/* + * $Id: PercentLength.java,v 1.6 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.expr.Numeric; + +/** + * a percent specified length quantity in XSL + */ +public class PercentLength extends Length { + + private double factor; + private PercentBase lbase = null; + + /** + * construct an object based on a factor (the percent, as a + * a factor) and an object which has a method to return the + * Length which provides the "base" for this calculation. + */ + public PercentLength(double factor) { + this(factor, null); + } + + public PercentLength(double factor, PercentBase lbase) { + this.factor = factor; + this.lbase = lbase; + } + + public void setBaseLength(PercentBase lbase) { + this.lbase = lbase; + } + + public PercentBase getBaseLength() { + return this.lbase; + } + + /** + * Return the computed value in millipoints. This assumes that the + * base length has been resolved to an absolute length value. + */ + protected void computeValue() { + setComputedValue((int)(factor * (double)lbase.getBaseLength())); + } + + public double value() { + return factor; + } + + public String toString() { + // return the factor as a percent + // What about the base value? + return (new Double(factor * 100.0).toString()) + "%"; + } + + public Numeric asNumeric() { + return new Numeric(this); + } + +} diff --git a/src/java/org/apache/fop/datatypes/Space.java b/src/java/org/apache/fop/datatypes/Space.java new file mode 100644 index 000000000..f9c779c96 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/Space.java @@ -0,0 +1,104 @@ +/* + * $Id: Space.java,v 1.8 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.Property; + +/** + * a space quantity in XSL (space-before, space-after) + */ +public class Space extends LengthRange { + + private Property precedence; + private Property conditionality; + + // From CompoundDatatype + public void setComponent(String sCmpnName, Property cmpnValue, + boolean bIsDefault) { + if (sCmpnName.equals("precedence")) { + setPrecedence(cmpnValue, bIsDefault); + } else if (sCmpnName.equals("conditionality")) { + setConditionality(cmpnValue, bIsDefault); + } else { + super.setComponent(sCmpnName, cmpnValue, bIsDefault); + } + } + + // From CompoundDatatype + public Property getComponent(String sCmpnName) { + if (sCmpnName.equals("precedence")) { + return getPrecedence(); + } else if (sCmpnName.equals("conditionality")) { + return getConditionality(); + } else { + return super.getComponent(sCmpnName); + } + } + + protected void setPrecedence(Property precedence, boolean bIsDefault) { + this.precedence = precedence; + } + + protected void setConditionality(Property conditionality, + boolean bIsDefault) { + this.conditionality = conditionality; + } + + public Property getPrecedence() { + return this.precedence; + } + + public Property getConditionality() { + return this.conditionality; + } + +} + diff --git a/src/java/org/apache/fop/datatypes/TableColLength.java b/src/java/org/apache/fop/datatypes/TableColLength.java new file mode 100644 index 000000000..7bc6ff991 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/TableColLength.java @@ -0,0 +1,111 @@ +/* + * $Id: TableColLength.java,v 1.6 2003/03/05 20:38:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.expr.Numeric; + +/** + * A table-column width specification, possibly including some + * number of proportional "column-units". The absolute size of a + * column-unit depends on the fixed and proportional sizes of all + * columns in the table, and on the overall size of the table. + * It can't be calculated until all columns have been specified and until + * the actual width of the table is known. Since this can be specified + * as a percent of its parent containing width, the calculation is done + * during layout. + * NOTE: this is only supposed to be allowed if table-layout=fixed. + */ +public class TableColLength extends Length { + + /** + * Number of table-column proportional units + */ + private double tcolUnits; + + /** + * Construct an object with tcolUnits of proportional measure. + */ + public TableColLength(double tcolUnits) { + this.tcolUnits = tcolUnits; + } + + /** + * Override the method in Length to return the number of specified + * proportional table-column units. + */ + public double getTableUnits() { + return tcolUnits; + } + + /** + * Calculate the number of millipoints and set it. + */ + public void resolveTableUnit(double mpointsPerUnit) { + setComputedValue((int)(tcolUnits * mpointsPerUnit)); + } + + //If the table-unit can be resolved, set the computed value + /*protected void computeValue() { + if (tblUnitBase.canResolveUnit()) { + rslt += (int)(tcolUnits * (double)tblUnitBase.getUnitValue()); + setComputedValue(rslt); + } + }*/ + + public String toString() { + return (Double.toString(tcolUnits) + " table-column-units"); + } + + public Numeric asNumeric() { + return new Numeric(this); + } +} + diff --git a/src/java/org/apache/fop/datatypes/ToBeImplemented.java b/src/java/org/apache/fop/datatypes/ToBeImplemented.java new file mode 100644 index 000000000..3354159c7 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/ToBeImplemented.java @@ -0,0 +1,62 @@ +/* + * $Id: ToBeImplemented.java,v 1.3 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +/** + * a not as yet implemented value + */ +public class ToBeImplemented { + + public ToBeImplemented(String value) { + } + +} + diff --git a/src/java/org/apache/fop/datatypes/ToBeImplementedProperty.java b/src/java/org/apache/fop/datatypes/ToBeImplementedProperty.java new file mode 100644 index 000000000..1b2bdbd75 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/ToBeImplementedProperty.java @@ -0,0 +1,87 @@ +/* + * $Id: ToBeImplementedProperty.java,v 1.6 2003/03/05 20:38:23 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.datatypes; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.PropertyList; + +public class ToBeImplementedProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String propName) { + super(propName); + } + + public Property convertProperty(Property p, + PropertyList propertyList, FObj fo) { + if (p instanceof ToBeImplementedProperty) { + return p; + } + ToBeImplementedProperty val = + new ToBeImplementedProperty(getPropName()); + return val; + } + } + + public ToBeImplementedProperty(String propName) { + + //XXX: (mjg@recalldesign.com) This is a bit of a kluge, perhaps an + //UnimplementedPropertyException or something similar should + //get thrown here instead. + +// Logger log = Hierarchy.getDefaultHierarchy().getLoggerFor("fop"); +// log.warn("property - \"" + propName +// + "\" is not implemented yet."); + } +} + diff --git a/src/java/org/apache/fop/datatypes/package.html b/src/java/org/apache/fop/datatypes/package.html new file mode 100644 index 000000000..05d202085 --- /dev/null +++ b/src/java/org/apache/fop/datatypes/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.datatypes Package + +

XSL Datatypes

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/extensions/BookmarkData.java b/src/java/org/apache/fop/extensions/BookmarkData.java new file mode 100644 index 000000000..1f5f04a8a --- /dev/null +++ b/src/java/org/apache/fop/extensions/BookmarkData.java @@ -0,0 +1,271 @@ +/* + * $Id: BookmarkData.java,v 1.5 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.TreeExt; +import org.apache.fop.area.AreaTree; + +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; + +/** + * This class holds the PDF bookmark extension data. + * This implements Resolveable and TreeExt so that it can be + * added to the area tree as a resolveable tree extension. + */ +public class BookmarkData implements Resolveable, TreeExt { + private ArrayList subData = new ArrayList(); + private HashMap idRefs = new HashMap(); + + // area tree for the top level object to notify when resolved + private AreaTree areaTree = null; + + private String idRef; + private PageViewport pageRef = null; + private String label = null; + + /** + * Create a new bookmark data object. + * This should only be call by the top level element as the + * id reference will be null. + */ + public BookmarkData() { + idRef = null; + } + + /** + * Create a new pdf bookmark data object. + * This is used by the outlines to create a data object + * with a id reference. The id reference is to be resolved. + * + * @param id the id reference + */ + public BookmarkData(String id) { + idRef = id; + idRefs.put(idRef, this); + } + + /** + * Set the area tree. + * This should only be called for the top level element. + * The area tree is used once resolving is complete. + * + * @param at the area tree for the current document + */ + public void setAreaTree(AreaTree at) { + areaTree = at; + } + + /** + * Get the id reference for this data. + * + * @return the id reference + */ + public String getID() { + return idRef; + } + + /** + * Add the child bookmark data object. + * This adds a child bookmark in the bookmark hierarchy. + * + * @param sub the child bookmark data + */ + public void addSubData(BookmarkData sub) { + subData.add(sub); + idRefs.put(sub.getID(), sub); + String[] ids = sub.getIDs(); + for (int count = 0; count < ids.length; count++) { + idRefs.put(ids[count], sub); + } + } + + /** + * Set the label for this bookmark. + * + * @param l the string label + */ + public void setLabel(String l) { + label = l; + } + + /** + * Get the label for this bookmark object. + * + * @return the label string + */ + public String getLabel() { + return label; + } + + /** + * Get the size of child data objects. + * + * @return the number of child bookmark data + */ + public int getCount() { + return subData.size(); + } + + /** + * Get the child data object. + * + * @param count the index to get + * @return the child bookmark data + */ + public BookmarkData getSubData(int count) { + return (BookmarkData)subData.get(count); + } + + /** + * Get the page that this resolves to. + * + * @return the PageViewport that this extension resolves to + */ + public PageViewport getPage() { + return pageRef; + } + + /** + * Check if this tree extension is resolveable. + * + * @return true since this also implements Resolveable + */ + public boolean isResolveable() { + return true; + } + + /** + * Get the mime type of this area tree extension. + * + * @return this tree extension applies to pdf + */ + public String getMimeType() { + return "application/pdf"; + } + + /** + * Get the name of this area tree extension. + * + * @return the name of the PDF bookmark extension is "Bookmark" + */ + public String getName() { + return "Bookmark"; + } + + /** + * Check if this resolveable object has been resolved. + * Once the id reference is null then it has been resolved. + * + * @return true if this has been resolved + */ + public boolean isResolved() { + return idRefs == null; + } + + /** + * Get the id references held by this object. + * Also includes all id references of all children. + * + * @return the array of id references + */ + public String[] getIDs() { + return (String[])idRefs.keySet().toArray(new String[] {}); + } + + /** + * Resolve this resolveable object. + * This resolves the id reference and if possible also + * resolves id references of child elements that have the same + * id reference. + * + * @param id the id reference being resolved + * @param pages the list of pages the the id reference resolves to + */ + public void resolve(String id, List pages) { + // this method is buggy + + if (!id.equals(idRef)) { + BookmarkData bd = (BookmarkData)idRefs.get(id); + idRefs.remove(id); + if (bd != null) { + bd.resolve(id, pages); + if (bd.isResolved()) { + checkFinish(); + } + } else if (idRef == null) { + checkFinish(); + } + } else { + if (pages != null) { + pageRef = (PageViewport)pages.get(0); + } + // TODO + // get rect area of id on page + + idRefs.remove(idRef); + checkFinish(); + } + } + + private void checkFinish() { + if (idRefs.size() == 0) { + idRefs = null; + if (areaTree != null) { + areaTree.handleTreeExtension(this, TreeExt.AFTER_PAGE); + } + } + } +} + diff --git a/src/java/org/apache/fop/extensions/Bookmarks.java b/src/java/org/apache/fop/extensions/Bookmarks.java new file mode 100644 index 000000000..da2ef1840 --- /dev/null +++ b/src/java/org/apache/fop/extensions/Bookmarks.java @@ -0,0 +1,118 @@ +/* + * $Id: Bookmarks.java,v 1.7 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.apps.LayoutHandler; +import org.apache.fop.fo.FONode; +import org.apache.fop.area.AreaTree; + +import java.util.ArrayList; + +/** + * Bookmarks data is the top level element of the pdf bookmark extension. + * This handles the adding of outlines. When the element is ended it + * creates the bookmark data and adds to the area tree. + */ +public class Bookmarks extends ExtensionObj { + private ArrayList outlines = new ArrayList(); + private BookmarkData data; + + /** + * Create a new Bookmarks object. + * + * @param parent the parent fo node + */ + public Bookmarks(FONode parent) { + super(parent); + } + + /** + * Add the child to the top level. + * This handles all Outline objects added and ignores others. + * + * @param obj the child to add + */ + protected void addChild(FONode obj) { + if (obj instanceof Outline) { + outlines.add(obj); + } + } + + /** + * Get the data created for this bookmark. + * + * @return the bookmark data + */ + public BookmarkData getData() { + return data; + } + + /** + * When this element is finished then it can create + * the bookmark data from the child elements and add + * the extension to the area tree. + */ + public void end() { + getLogger().debug("adding bookmarks to area tree"); + data = new BookmarkData(); + for (int count = 0; count < outlines.size(); count++) { + Outline out = (Outline)outlines.get(count); + data.addSubData(out.getData()); + } + // add data to area tree for resolving and handling + if (structHandler instanceof LayoutHandler) { + AreaTree at = ((LayoutHandler)structHandler).getAreaTree(); + at.addTreeExtension(data); + data.setAreaTree(at); + } + } +} + diff --git a/src/java/org/apache/fop/extensions/ExtensionElementMapping.java b/src/java/org/apache/fop/extensions/ExtensionElementMapping.java new file mode 100644 index 000000000..283bc6e68 --- /dev/null +++ b/src/java/org/apache/fop/extensions/ExtensionElementMapping.java @@ -0,0 +1,111 @@ +/* + * $Id: ExtensionElementMapping.java,v 1.10 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ElementMapping; +import org.apache.fop.fo.FOTreeBuilder; + +import java.util.HashMap; + +/** + * Element mapping for the pdf bookmark extension. + * This sets up the mapping for the classes that handle the + * pdf bookmark extension. + */ +public class ExtensionElementMapping implements ElementMapping { + /** + * The pdf bookmark extension uri + */ + public static final String URI = "http://xml.apache.org/fop/extensions"; + + // the mappings are only setup once and resued after that + private static HashMap foObjs = null; + + private static synchronized void setupExt() { + if (foObjs == null) { + foObjs = new HashMap(); + foObjs.put("bookmarks", new B()); + foObjs.put("outline", new O()); + foObjs.put("label", new L()); + } + } + + /** + * Add the mappings to the fo tree builder. + * + * @param builder the fo tree builder to add the mappings + */ + public void addToBuilder(FOTreeBuilder builder) { + if (foObjs == null) { + setupExt(); + } + builder.addMapping(URI, foObjs); + } + + static class B extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Bookmarks(parent); + } + } + + static class O extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Outline(parent); + } + } + + static class L extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Label(parent); + } + } +} diff --git a/src/java/org/apache/fop/extensions/ExtensionObj.java b/src/java/org/apache/fop/extensions/ExtensionObj.java new file mode 100644 index 000000000..05d6a63e4 --- /dev/null +++ b/src/java/org/apache/fop/extensions/ExtensionObj.java @@ -0,0 +1,71 @@ +/* + * $Id: ExtensionObj.java,v 1.7 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; + +/** + * Base class for pdf bookmark extension objects. + */ +public abstract class ExtensionObj extends FObj { + + /** + * Create a new extension object. + * + * @param parent the parent formatting object + */ + public ExtensionObj(FONode parent) { + super(parent); + } + +} + diff --git a/src/java/org/apache/fop/extensions/Label.java b/src/java/org/apache/fop/extensions/Label.java new file mode 100644 index 000000000..da4068cf5 --- /dev/null +++ b/src/java/org/apache/fop/extensions/Label.java @@ -0,0 +1,92 @@ +/* + * $Id: Label.java,v 1.7 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.fo.FONode; + +/** + * Labal for PDF bookmark extension. + * This element contains the label for the bookmark object. + */ +public class Label extends ExtensionObj { + private String label = ""; + + /** + * Create a new label object. + * + * @param parent the fo node parent + */ + public Label(FONode parent) { + super(parent); + } + + /** + * Add the characters to this label. + * The text data inside the label xml element is used for the label string. + * + * @param data the character data + * @param start the start position in the data array + * @param end the end position in the character array + */ + protected void addCharacters(char data[], int start, int end) { + label += new String(data, start, end - start); + } + + /** + * Get the string for this label. + * + * @return the label string + */ + public String toString() { + return label; + } + +} diff --git a/src/java/org/apache/fop/extensions/Outline.java b/src/java/org/apache/fop/extensions/Outline.java new file mode 100644 index 000000000..061d3705c --- /dev/null +++ b/src/java/org/apache/fop/extensions/Outline.java @@ -0,0 +1,144 @@ +/* + * $Id: Outline.java,v 1.10 2003/03/05 20:40:18 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.extensions; + +import org.apache.fop.fo.FONode; +import org.apache.fop.apps.FOPException; + +import java.util.ArrayList; + +import org.xml.sax.Attributes; + +/** + * The outline object for the pdf bookmark extension. + * The outline element contains a label and optionally more outlines. + */ +public class Outline extends ExtensionObj { + private Label label; + private ArrayList outlines = new ArrayList(); + + private String internalDestination; + private String externalDestination; + + /** + * Create a new outline object. + * + * @param parent the parent fo node + */ + public Outline(FONode parent) { + super(parent); + } + + /** + * The attribues on the outline object are the internal and external + * destination. One of these is required. + * + * @param attlist the attribute list + * @throws FOPException a fop exception if there is an error + */ + public void handleAttrs(Attributes attlist) throws FOPException { + internalDestination = + attlist.getValue("internal-destination"); + externalDestination = + attlist.getValue("external-destination"); + if (externalDestination != null && !externalDestination.equals("")) { + getLogger().warn("fox:outline external-destination not supported currently."); + } + + if (internalDestination == null || internalDestination.equals("")) { + getLogger().warn("fox:outline requires an internal-destination."); + } + + } + + /** + * Add the child to this outline. + * This checks for the type, label or outline and handles appropriately. + * + * @param obj the child object + */ + protected void addChild(FONode obj) { + if (obj instanceof Label) { + label = (Label)obj; + } else if (obj instanceof Outline) { + outlines.add(obj); + } + } + + /** + * Get the bookmark data for this outline. + * This creates a bookmark data with the destination + * and adds all the data from child outlines. + * + * @return the new bookmark data + */ + public BookmarkData getData() { + BookmarkData data = new BookmarkData(internalDestination); + data.setLabel(getLabel()); + for (int count = 0; count < outlines.size(); count++) { + Outline out = (Outline)outlines.get(count); + data.addSubData(out.getData()); + } + return data; + } + + /** + * Get the label string. + * This gets the label string from the child label element. + * + * @return the label string or empty if not found + */ + public String getLabel() { + return label == null ? "" : label.toString(); + } + +} + diff --git a/src/java/org/apache/fop/fo/AbstractCharIterator.java b/src/java/org/apache/fop/fo/AbstractCharIterator.java new file mode 100644 index 000000000..82b8d59b6 --- /dev/null +++ b/src/java/org/apache/fop/fo/AbstractCharIterator.java @@ -0,0 +1,102 @@ +/* + * $Id: AbstractCharIterator.java,v 1.4 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.NoSuchElementException; + +/** + * Abstract base class for character iterators. + */ +public abstract class AbstractCharIterator implements CharIterator, Cloneable { + + /** + * @see java.util.Iterator#hasNext() + */ + public abstract boolean hasNext(); + + /** + * @see org.apache.fop.fo.CharIterator#nextChar() + */ + public abstract char nextChar() throws NoSuchElementException ; + + /** + * @see java.util.Iterator#next() + */ + public Object next() throws NoSuchElementException { + return new Character(nextChar()); + } + + /** + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + + /** + * @see org.apache.fop.fo.CharIterator#replaceChar(char) + */ + public void replaceChar(char c) { + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + return null; + } + } +} + diff --git a/src/java/org/apache/fop/fo/BoxPropShorthandParser.java b/src/java/org/apache/fop/fo/BoxPropShorthandParser.java new file mode 100644 index 000000000..6fe1a2f73 --- /dev/null +++ b/src/java/org/apache/fop/fo/BoxPropShorthandParser.java @@ -0,0 +1,88 @@ +/* + * $Id: BoxPropShorthandParser.java,v 1.3 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +public class BoxPropShorthandParser extends GenericShorthandParser { + + /** + * @see org.apache.fop.fo.GenericShorthandParser#GenericShorthandParser(ListProperty) + */ + public BoxPropShorthandParser(ListProperty listprop) { + super(listprop); + } + + /** + * Stores 1 to 4 values of same type. + * Set the given property based on the number of values set. + * Example: padding, border-width, border-color, border-style, margin + * @see org.apache.fop.fo.GenericShorthandParser#convertValueForProperty(String, Maker, PropertyList) + */ + protected Property convertValueForProperty(String propName, + Property.Maker maker, + PropertyList propertyList) { + Property p = null; + if (propName.indexOf("-top") >= 0) { + p = getElement(0); + } else if (propName.indexOf("-right") >= 0) { + p = getElement(count() > 1 ? 1 : 0); + } else if (propName.indexOf("-bottom") >= 0) { + p = getElement(count() > 2 ? 2 : 0); + } else if (propName.indexOf("-left") >= 0) { + p = getElement(count() > 3 ? 3 : (count() > 1 ? 1 : 0)); + } + // if p not null, try to convert it to a value of the correct type + if (p != null) { + return maker.convertShorthandProperty(propertyList, p, null); + } + return p; + } + +} diff --git a/src/java/org/apache/fop/fo/CharIterator.java b/src/java/org/apache/fop/fo/CharIterator.java new file mode 100644 index 000000000..05c0c8c38 --- /dev/null +++ b/src/java/org/apache/fop/fo/CharIterator.java @@ -0,0 +1,62 @@ +/* + * $Id: CharIterator.java,v 1.2 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.Iterator; +import java.util.NoSuchElementException; + + +public interface CharIterator extends Iterator { + + char nextChar() throws NoSuchElementException ; + void replaceChar(char c); + Object clone(); +} diff --git a/src/java/org/apache/fop/fo/CharacterProperty.java b/src/java/org/apache/fop/fo/CharacterProperty.java new file mode 100644 index 000000000..517b91a8b --- /dev/null +++ b/src/java/org/apache/fop/fo/CharacterProperty.java @@ -0,0 +1,87 @@ +/* + * $Id: CharacterProperty.java,v 1.3 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +public class CharacterProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String propName) { + super(propName); + } + + public Property make(PropertyList propertyList, String value, + FObj fo) { + char c = value.charAt(0); + return new CharacterProperty(c); + } + + } // end Charakter.Maker + + private char character; + + public CharacterProperty(char character) { + this.character = character; + } + + public Object getObject() { + return new Character(character); + } + + public char getCharacter() { + return this.character; + } + + public String getString() { + return new Character(character).toString(); + } + +} diff --git a/src/java/org/apache/fop/fo/ColorProfile.java b/src/java/org/apache/fop/fo/ColorProfile.java new file mode 100644 index 000000000..da432d826 --- /dev/null +++ b/src/java/org/apache/fop/fo/ColorProfile.java @@ -0,0 +1,120 @@ +/* + * $Id: ColorProfile.java,v 1.10 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.awt.color.ICC_Profile; +import java.awt.color.ICC_ColorSpace; +import java.net.URL; +import java.io.IOException; +import java.io.InputStream; + +// FOP +import org.apache.fop.datatypes.ColorType; + +/** + * The fo:color-profile formatting object. + * This loads the color profile when needed and resolves a requested color. + */ +public class ColorProfile extends FObj { + private int intent; + private String src; + private String profileName; + private ICC_ColorSpace colorSpace = null; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + protected ColorProfile(FONode parent) { + super(parent); + } + + public void end() { + src = this.properties.get("src").getString(); + profileName = this.properties.get("color-profile-name").getString(); + intent = this.properties.get("rendering-intent").getEnum(); + this.properties = null; + } + + /** + * Get the name of this color profile. + */ + public String getProfileName() { + return profileName; + } + + /** + * Get the color specified with the color values from the color profile. + * The default values are used if the profile could not be loaded + * or the value is not found. + */ + public ColorType getColor(int[] colorVals, int defR, int defG, int defB) { + // float[] rgbvals = colorSpace.toRGB(colorVals); + // return new ColorType(rgbvals); + return null; + } + + /** + * Load the color profile. + */ + private void load() { + try { + URL url = new URL(src); + InputStream is = url.openStream(); + ICC_Profile iccProfile = ICC_Profile.getInstance(is); + colorSpace = new ICC_ColorSpace(iccProfile); + } catch (IOException ioe) { + getLogger().error("Could not read Color Profile src", ioe); + } catch (IllegalArgumentException iae) { + getLogger().error("Color Profile src not an ICC Profile", iae); + } + } +} diff --git a/src/java/org/apache/fop/fo/ColorTypeProperty.java b/src/java/org/apache/fop/fo/ColorTypeProperty.java new file mode 100644 index 000000000..de02dd2c1 --- /dev/null +++ b/src/java/org/apache/fop/fo/ColorTypeProperty.java @@ -0,0 +1,93 @@ +/* + * $Id: ColorTypeProperty.java,v 1.5 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.ColorType; + +public class ColorTypeProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String propName) { + super(propName); + } + + public Property convertProperty(Property p, + PropertyList propertyList, FObj fo) { + if (p instanceof ColorTypeProperty) { + return p; + } + ColorType val = p.getColorType(); + if (val != null) { + return new ColorTypeProperty(val); + } + return convertPropertyDatatype(p, propertyList, fo); + } + + } + + private ColorType colorType; + + public ColorTypeProperty(ColorType colorType) { + this.colorType = colorType; + } + + // Can't convert to any other types + public ColorType getColorType() { + return this.colorType; + } + + public Object getObject() { + return this.colorType; + } + +} + diff --git a/src/java/org/apache/fop/fo/CondLengthProperty.java b/src/java/org/apache/fop/fo/CondLengthProperty.java new file mode 100644 index 000000000..564ead0df --- /dev/null +++ b/src/java/org/apache/fop/fo/CondLengthProperty.java @@ -0,0 +1,85 @@ +/* + * $Id: CondLengthProperty.java,v 1.5 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.CondLength; + +public class CondLengthProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String name) { + super(name); + } + + } + + private CondLength condLength = null; + + public CondLengthProperty(CondLength condLength) { + this.condLength = condLength; + } + + public CondLength getCondLength() { + return this.condLength; + } + + /* Question, should we allow this? */ + public Length getLength() { + return this.condLength.getLength().getLength(); + } + + public Object getObject() { + return this.condLength; + } + +} diff --git a/src/java/org/apache/fop/fo/Declarations.java b/src/java/org/apache/fop/fo/Declarations.java new file mode 100644 index 000000000..6dfb9aa61 --- /dev/null +++ b/src/java/org/apache/fop/fo/Declarations.java @@ -0,0 +1,107 @@ +/* + * $Id: Declarations.java,v 1.8 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.List; +import java.util.Map; +import java.util.Iterator; + +/** + * Declarations formatting object. + * A declarations formatting object holds a set of color-profiles + * and optionally additional non-XSL namespace elements. + * The color-profiles are held in a hashmap for use with color-profile + * references. + */ +public class Declarations extends FObj { + + private Map colorProfiles = null; + private List external = null; + + protected Declarations(FONode parent) { + super(parent); + } + + /** + * At then end of this element sort out the child into + * a hashmap of color profiles and a list of external xml. + */ + public void end() { + for (Iterator iter = children.iterator(); iter.hasNext();) { + FONode node = (FONode)iter.next(); + if (node.getName().equals("fo:color-profile")) { + ColorProfile cp = (ColorProfile)node; + if (!"".equals(cp.getProfileName())) { + if (colorProfiles == null) { + colorProfiles = new java.util.HashMap(); + } + if (colorProfiles.get(cp.getProfileName()) != null) { + // duplicate names + getLogger().warn("Duplicate fo:color-profile profile name : " + + cp.getProfileName()); + } + colorProfiles.put(cp.getProfileName(), cp); + } else { + getLogger().warn("color-profile-name required for color profile"); + } + } else if (node instanceof XMLObj) { + if (external == null) { + external = new java.util.ArrayList(); + } + external.add(node); + } else { + getLogger().warn("invalid element " + node.getName() + "inside declarations"); + } + } + children = null; + } +} diff --git a/src/java/org/apache/fop/fo/ElementMapping.java b/src/java/org/apache/fop/fo/ElementMapping.java new file mode 100644 index 000000000..331ca2a85 --- /dev/null +++ b/src/java/org/apache/fop/fo/ElementMapping.java @@ -0,0 +1,67 @@ +/* + * $Id: ElementMapping.java,v 1.11 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +/** + * Interface for adding supported element and property mappings to + * the given builder. + */ +public interface ElementMapping { + final String DEFAULT = ""; + + void addToBuilder(FOTreeBuilder builder); + + public static class Maker { + public FONode make(FONode parent) { + return null; + } + } +} diff --git a/src/java/org/apache/fop/fo/EnumProperty.java b/src/java/org/apache/fop/fo/EnumProperty.java new file mode 100644 index 000000000..e34bef87c --- /dev/null +++ b/src/java/org/apache/fop/fo/EnumProperty.java @@ -0,0 +1,104 @@ +/* + * $Id: EnumProperty.java,v 1.8 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.apps.FOPException; + +public class EnumProperty extends Property { + + public static class Maker extends Property.Maker { + + protected Maker(String propName) { + super(propName); + } + + /** + * Called by subclass if no match found. + */ + public Property checkEnumValues(String value) { + //log.error("Unknown enumerated value for property '" + // + getPropName() + "': " + value); + return null; + } + + protected Property findConstant(String value) { + return null; + } + + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) throws FOPException { + if (p instanceof EnumProperty) { + return p; + } else { + return null; + } + } + } + + private int value; + + public EnumProperty(int explicitValue) { + this.value = explicitValue; + } + + public int getEnum() { + return this.value; + } + + public Object getObject() { + // FIXME: return String value: property must reference maker + // return maker.getEnumValue(this.value); + return new Integer(this.value); + } + +} + diff --git a/src/java/org/apache/fop/fo/FOElementMapping.java b/src/java/org/apache/fop/fo/FOElementMapping.java new file mode 100644 index 000000000..f9db7f51c --- /dev/null +++ b/src/java/org/apache/fop/fo/FOElementMapping.java @@ -0,0 +1,486 @@ +/* + * $Id: FOElementMapping.java,v 1.5 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.HashMap; + +/** + * Element mapping class for all XSL-FO elements. + */ +public class FOElementMapping implements ElementMapping { + + private static HashMap foObjs = null; + + private static synchronized void setupFO() { + if (foObjs == null) { + foObjs = new HashMap(); + + // Declarations and Pagination and Layout Formatting Objects + foObjs.put("root", new R()); + foObjs.put("declarations", new Dec()); + foObjs.put("color-profile", new CP()); + foObjs.put("page-sequence", new PS()); + foObjs.put("layout-master-set", new LMS()); + foObjs.put("page-sequence-master", + new PSM()); + foObjs.put("single-page-master-reference", + new SPMR()); + foObjs.put("repeatable-page-master-reference", + new RPMR()); + foObjs.put("repeatable-page-master-alternatives", + new RPMA()); + foObjs.put("conditional-page-master-reference", + new CPMR()); + foObjs.put("simple-page-master", + new SPM()); + foObjs.put("region-body", new RB()); + foObjs.put("region-before", new RBefore()); + foObjs.put("region-after", new RA()); + foObjs.put("region-start", new RS()); + foObjs.put("region-end", new RE()); + foObjs.put("flow", new Fl()); + foObjs.put("static-content", new SC()); + foObjs.put("title", new T()); + + // Block-level Formatting Objects + foObjs.put("block", new B()); + foObjs.put("block-container", new BC()); + + // Inline-level Formatting Objects + foObjs.put("bidi-override", new BO()); + foObjs.put("character", + new Ch()); + foObjs.put("initial-property-set", + new IPS()); + foObjs.put("external-graphic", new EG()); + foObjs.put("instream-foreign-object", + new IFO()); + foObjs.put("inline", new In()); + foObjs.put("inline-container", new IC()); + foObjs.put("leader", new L()); + foObjs.put("page-number", new PN()); + foObjs.put("page-number-citation", + new PNC()); + + // Formatting Objects for Tables + foObjs.put("table-and-caption", new TAC()); + foObjs.put("table", new Ta()); + foObjs.put("table-column", new TC()); + foObjs.put("table-caption", new TCaption()); + foObjs.put("table-header", new TB()); + foObjs.put("table-footer", new TB()); + foObjs.put("table-body", new TB()); + foObjs.put("table-row", new TR()); + foObjs.put("table-cell", new TCell()); + + // Formatting Objects for Lists + foObjs.put("list-block", new LB()); + foObjs.put("list-item", new LI()); + foObjs.put("list-item-body", new LIB()); + foObjs.put("list-item-label", new LIL()); + + // Dynamic Effects: Link and Multi Formatting Objects + foObjs.put("basic-link", new BL()); + foObjs.put("multi-switch", new MS()); + foObjs.put("multi-case", new MC()); + foObjs.put("multi-toggle", new MT()); + foObjs.put("multi-properties", new MP()); + foObjs.put("multi-property-set", + new MPS()); + + // Out-of-Line Formatting Objects + foObjs.put("float", + new F()); + foObjs.put("footnote", new Foot()); + foObjs.put("footnote-body", new FB()); + + // Other Formatting Objects + foObjs.put("wrapper", new W()); + foObjs.put("marker", new M()); + foObjs.put("retrieve-marker", new RM()); + } + + } + + /** + * @see org.apache.fop.fo.ElementMapping#addToBuilder(FOTreeBuilder) + */ + public void addToBuilder(FOTreeBuilder builder) { + setupFO(); + String uri = "http://www.w3.org/1999/XSL/Format"; + builder.addMapping(uri, foObjs); + } + + static class R extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.Root(parent); + } + } + + static class Dec extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Declarations(parent); + } + } + + static class CP extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new ColorProfile(parent); + } + } + + static class PS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.PageSequence(parent); + } + } + + static class LMS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.LayoutMasterSet(parent); + } + } + + static class PSM extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.PageSequenceMaster(parent); + } + } + + static class SPMR extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.SinglePageMasterReference(parent); + } + } + + static class RPMR extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RepeatablePageMasterReference(parent); + } + } + + static class RPMA extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RepeatablePageMasterAlternatives(parent); + } + } + + static class CPMR extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.ConditionalPageMasterReference(parent); + } + } + + static class SPM extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.SimplePageMaster(parent); + } + } + + static class RB extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RegionBody(parent); + } + } + + static class RBefore extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RegionBefore(parent); + } + } + + static class RA extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RegionAfter(parent); + } + } + + static class RS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RegionStart(parent); + } + } + + static class RE extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.pagination.RegionEnd(parent); + } + } + + static class Fl extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Flow(parent); + } + } + + static class SC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.StaticContent(parent); + } + } + + static class T extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Title(parent); + } + } + + static class B extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Block(parent); + } + } + + static class BC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.BlockContainer(parent); + } + } + + static class BO extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.BidiOverride(parent); + } + } + + static class Ch extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Character(parent); + } + } + + static class IPS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.InitialPropertySet(parent); + } + } + + static class EG extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ExternalGraphic(parent); + } + } + + static class IFO extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.InstreamForeignObject(parent); + } + } + + static class In extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Inline(parent); + } + } + + static class IC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.InlineContainer(parent); + } + } + + static class L extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Leader(parent); + } + } + + static class PN extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.PageNumber(parent); + } + } + + static class PNC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.PageNumberCitation(parent); + } + } + + static class TAC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableAndCaption(parent); + } + } + + static class Ta extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Table(parent); + } + } + + static class TC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableColumn(parent); + } + } + + static class TCaption extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableCaption(parent); + } + } + + static class TB extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableBody(parent); + } + } + + static class TR extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableRow(parent); + } + } + + static class TCell extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.TableCell(parent); + } + } + + static class LB extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ListBlock(parent); + } + } + + static class LI extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ListItem(parent); + } + } + + static class LIB extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ListItemBody(parent); + } + } + + static class LIL extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.ListItemLabel(parent); + } + } + + static class BL extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.BasicLink(parent); + } + } + + static class MS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.MultiSwitch(parent); + } + } + + static class MC extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.MultiCase(parent); + } + } + + static class MT extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.MultiToggle(parent); + } + } + + static class MP extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.MultiProperties(parent); + } + } + + static class MPS extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.MultiPropertySet(parent); + } + } + + static class F extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Float(parent); + } + } + + static class Foot extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Footnote(parent); + } + } + + static class FB extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.FootnoteBody(parent); + } + } + + static class W extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Wrapper(parent); + } + } + + static class M extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.Marker(parent); + } + } + + static class RM extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new org.apache.fop.fo.flow.RetrieveMarker(parent); + } + } +} diff --git a/src/java/org/apache/fop/fo/FONode.java b/src/java/org/apache/fop/fo/FONode.java new file mode 100644 index 000000000..240efac8e --- /dev/null +++ b/src/java/org/apache/fop/fo/FONode.java @@ -0,0 +1,203 @@ +/* + * $Id: FONode.java,v 1.34 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.ListIterator; + +// XML +import org.xml.sax.Attributes; + +// Avalon +import org.apache.avalon.framework.logger.Logger; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.util.CharUtilities; + +/** + * base class for nodes in the XML tree + * + */ +public abstract class FONode { + + /** FO User Agent for this node (for logger etc.)*/ + protected FOUserAgent userAgent; + /** Parent FO node */ + protected FONode parent; + /** Name of the node */ + protected String name; + + /** + * Main constructor. + * @param parent parent of this node + */ + protected FONode(FONode parent) { + this.parent = parent; + } + + /** + * Sets the name of the node. + * @param str the name + */ + public void setName(String str) { + name = str; + } + + /** + * Returns the logger for the node. + * @return the logger + */ + protected Logger getLogger() { + return userAgent.getLogger(); + } + + /** + * Sets the user agent for the node. + * @param ua the user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + /** + * Returns the user agent for the node. + * @return FOUserAgent + */ + protected FOUserAgent getUserAgent() { + return userAgent; + } + + /** + * Sets the structure handler to send events to. + * @param st StructureHandler instance + */ + public void setStructHandler(StructureHandler st) { + } + + public void handleAttrs(Attributes attlist) throws FOPException { + } + + /** + * Returns the name of the object + * @return the name of this object + */ + public String getName() { + return this.name; + } + + /** + * Adds characters (does nothing here) + * @param data text + * @param start start position + * @param length length of the text + */ + protected void addCharacters(char data[], int start, int length) { + // ignore + } + + /** + * + */ + protected void start() { + // do nothing by default + } + + /** + * + */ + protected void end() { + // do nothing by default + } + + protected void addChild(FONode child) { + } + + public FONode getParent() { + return this.parent; + } + + /** + * Return an iterator over all the children of this FObj. + * @return A ListIterator. + */ + public ListIterator getChildren() { + return null; + } + + /** + * Return an iterator over the object's children starting + * at the pased node. + * @param childNode First node in the iterator + * @return A ListIterator or null if childNode isn't a child of + * this FObj. + */ + public ListIterator getChildren(FONode childNode) { + return null; + } + + public CharIterator charIterator() { + return new OneCharIterator(CharUtilities.CODE_EOT); + } + + /** + * This is a quick check to see if it is a marker. + * This is needed since there is no other quick way of checking + * for a marker and not adding to the child list. + * + * @return true if this is a marker + */ + protected boolean isMarker() { + return false; + } +} + diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java new file mode 100644 index 000000000..80d2af61b --- /dev/null +++ b/src/java/org/apache/fop/fo/FOText.java @@ -0,0 +1,180 @@ +/* + * $Id: FOText.java,v 1.43 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.NoSuchElementException; +import java.util.List; + +// FOP +import org.apache.fop.layout.TextState; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.TextLayoutManager; +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.fo.properties.WhiteSpaceCollapse; + +/** + * A text node in the formatting object tree. + * + * Modified by Mark Lillywhite, mark-fop@inomial.com. + * Unfortunately the BufferManager implementatation holds + * onto references to the character data in this object + * longer than the lifetime of the object itself, causing + * excessive memory consumption and OOM errors. + */ +public class FOText extends FObj { + + protected char[] ca; + protected int start; + protected int length; + TextInfo textInfo; + TextState ts; + + public FOText(char[] chars, int s, int e, TextInfo ti) { + super(null); + this.start = 0; + this.ca = new char[e - s]; + System.arraycopy(chars, s, ca, 0, e - s); + this.length = e - s; + textInfo = ti; + } + + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + structHandler.characters(ca, start, length); + } + + /** + * Check if this text node will create an area. + * This means either there is non-whitespace or it is + * preserved whitespace. + * Maybe this just needs to check length > 0, since char iterators + * handle whitespace. + * + * @return true if this will create an area in the output + */ + public boolean willCreateArea() { + if (textInfo.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE + && length > 0) { + return true; + } + + for (int i = start; i < start + length; i++) { + char ch = ca[i]; + if (!((ch == ' ') + || (ch == '\n') + || (ch == '\r') + || (ch == '\t'))) { // whitespace + return true; + } + } + return false; + } + + public void addLayoutManager(List list) { + // if nothing left (length=0)? + if (length == 0) { + return; + } + + if (length < ca.length) { + char[] tmp = ca; + ca = new char[length]; + System.arraycopy(tmp, 0, ca, 0, length); + } + LayoutManager lm = new TextLayoutManager(ca, textInfo); + lm.setFObj(this); + list.add(lm); + } + + public CharIterator charIterator() { + return new TextCharIterator(); + } + + private class TextCharIterator extends AbstractCharIterator { + private int curIndex = 0; + + public boolean hasNext() { + return (curIndex < length); + } + + public char nextChar() { + if (curIndex < length) { + // Just a char class? Don't actually care about the value! + return ca[curIndex++]; + } else { + throw new NoSuchElementException(); + } + } + + public void remove() { + if (curIndex > 0 && curIndex < length) { + // copy from curIndex to end to curIndex-1 + System.arraycopy(ca, curIndex, ca, curIndex - 1, + length - curIndex); + length--; + curIndex--; + } else if (curIndex == length) { + curIndex = --length; + } + } + + + public void replaceChar(char c) { + if (curIndex > 0 && curIndex <= length) { + ca[curIndex - 1] = c; + } + } + + + } +} + diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java new file mode 100644 index 000000000..4a10e4889 --- /dev/null +++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java @@ -0,0 +1,275 @@ +/* + * $Id: FOTreeBuilder.java,v 1.43 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.StructureHandler; + +// Java +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +// SAX +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.SAXException; +import org.xml.sax.Attributes; + +// Avalon +import org.apache.avalon.framework.logger.Logger; + +/** + * SAX Handler that builds the formatting object tree. + * + * Modified by Mark Lillywhite mark-fop@inomial.com. Now uses + * StreamRenderer to automagically render the document as + * soon as it receives a page-sequence end-tag. Also, + * calls methods to set up and shut down the renderer at + * the beginning and end of the FO document. Finally, + * supresses adding the PageSequence object to the Root, + * since it is parsed immediately. + */ +public class FOTreeBuilder extends DefaultHandler { + + /** + * Table mapping element names to the makers of objects + * representing formatting objects. + */ + protected Map fobjTable = new java.util.HashMap(); + + /** + * Set of mapped namespaces. + */ + protected Set namespaces = new java.util.HashSet(); + + /** + * Current formatting object being handled + */ + protected FONode currentFObj = null; + + /** + * The root of the formatting object tree + */ + protected FONode rootFObj = null; + + /** + * The class that handles formatting and rendering to a stream + * (mark-fop@inomial.com) + */ + private StructureHandler structHandler; + + private FOUserAgent userAgent; + + /** + * Default constructor + */ + public FOTreeBuilder() { + } + + private Logger getLogger() { + return userAgent.getLogger(); + } + + /** + * Sets the user agent + * @param ua the user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + private FOUserAgent getUserAgent() { + return userAgent; + } + + /** + * Sets the structure handler to receive events. + * @param sh StructureHandler instance + */ + public void setStructHandler(StructureHandler sh) { + this.structHandler = sh; + } + + /** + * Adds a mapping from a namespace to a table of makers. + * + * @param namespaceURI namespace URI of formatting object elements + * @param table table of makers + */ + public void addMapping(String namespaceURI, HashMap table) { + this.fobjTable.put(namespaceURI, table); + this.namespaces.add(namespaceURI.intern()); + } + + /** + * SAX Handler for characters + * @see org.xml.sax.ContentHandler#characters(char[], int, int) + */ + public void characters(char data[], int start, int length) { + if (currentFObj != null) { + currentFObj.addCharacters(data, start, start + length); + } + } + + /** + * SAX Handler for the end of an element + * @see org.xml.sax.ContentHandler#endElement(String, String, String) + */ + public void endElement(String uri, String localName, String rawName) + throws SAXException { + currentFObj.end(); + currentFObj = currentFObj.getParent(); + } + + /** + * SAX Handler for the start of the document + * @see org.xml.sax.ContentHandler#startDocument() + */ + public void startDocument() throws SAXException { + rootFObj = null; // allows FOTreeBuilder to be reused + if (getLogger().isDebugEnabled()) { + getLogger().debug("Building formatting object tree"); + } + structHandler.startDocument(); + } + + /** + * SAX Handler for the end of the document + * @see org.xml.sax.ContentHandler#endDocument() + */ + public void endDocument() throws SAXException { + rootFObj = null; + currentFObj = null; + if (getLogger().isDebugEnabled()) { + getLogger().debug("Parsing of document complete"); + } + structHandler.endDocument(); + } + + /** + * SAX Handler for the start of an element + * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) + */ + public void startElement(String uri, String localName, String rawName, + Attributes attlist) throws SAXException { + /* the formatting object started */ + FONode fobj; + + /* the maker for the formatting object started */ + ElementMapping.Maker fobjMaker = null; + + Map table = (Map)fobjTable.get(uri); + if (table != null) { + fobjMaker = (ElementMapping.Maker)table.get(localName); + // try default + if (fobjMaker == null) { + fobjMaker = (ElementMapping.Maker)table.get(ElementMapping.DEFAULT); + } + } + + if (fobjMaker == null) { + if (getLogger().isWarnEnabled()) { + getLogger().warn("Unknown formatting object " + uri + "^" + localName); + } + if (namespaces.contains(uri.intern())) { + // fall back + fobjMaker = new Unknown.Maker(); + } else { + fobjMaker = new UnknownXMLObj.Maker(uri); + } + } + + try { + fobj = fobjMaker.make(currentFObj); + fobj.setName(localName); + // set the user agent for resolving user agent values + fobj.setUserAgent(userAgent); + // set the structure handler so that appropriate + // elements can signal structure events + fobj.setStructHandler(structHandler); + + fobj.handleAttrs(attlist); + } catch (FOPException e) { + throw new SAXException(e); + } + + if (rootFObj == null) { + if (!fobj.getName().equals("fo:root")) { + throw new SAXException(new FOPException("Root element must" + + " be fo:root, not " + + fobj.getName())); + } + rootFObj = fobj; + } else { + currentFObj.addChild(fobj); + } + + currentFObj = fobj; + } + + /** + * Resets this object for another run. + */ + public void reset() { + currentFObj = null; + rootFObj = null; + structHandler = null; + } + + /** + * Indicates if data has been processed. + * @return True if data has been processed + */ + public boolean hasData() { + return (rootFObj != null); + } +} diff --git a/src/java/org/apache/fop/fo/FOUserAgent.java b/src/java/org/apache/fop/fo/FOUserAgent.java new file mode 100644 index 000000000..b35fd6426 --- /dev/null +++ b/src/java/org/apache/fop/fo/FOUserAgent.java @@ -0,0 +1,220 @@ +/* + * $Id: FOUserAgent.java,v 1.15 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.Map; +import java.io.IOException; +import java.io.InputStream; + +// XML +import org.w3c.dom.Document; + +// Avalon +import org.apache.avalon.framework.logger.LogEnabled; +import org.apache.avalon.framework.logger.Logger; + +// FOP +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; + +/** + * The User Agent for fo. + * This user agent is used by the processing to obtain user configurable + * options. + *

+ * Renderer specific extensions (that do not produce normal areas on + * the output) will be done like so: + *
+ * The extension will create an area, custom if necessary + *
+ * this area will be added to the user agent with a key + *
+ * the renderer will know keys for particular extensions + *
+ * eg. bookmarks will be held in a special hierarchical area representing + * the title and bookmark structure + *
+ * These areas may contain resolveable areas that will be processed + * with other resolveable areas + */ +public class FOUserAgent implements LogEnabled { + + private Logger log; + private Map defaults = new java.util.HashMap(); + private Map handlers = new java.util.HashMap(); + private String baseURL; + + /** + * Sets the logger. + * @param log Logger to use + * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(Logger) + */ + public void enableLogging(Logger log) { + this.log = log; + } + + /** + * Returns the logger to use. + * @see org.apache.avalon.framework.logger.AbstractLogEnabled#getLogger() + * @todo This breaks IoC/SoC. Should be improved. + */ + public Logger getLogger() { + return this.log; + } + + /** + * Sets the base URL. + * @param baseURL base URL + */ + public void setBaseURL(String baseURL) { + this.baseURL = baseURL; + } + + /** + * Returns the base URL. + * @return the base URL + */ + public String getBaseURL() { + if ((this.baseURL == null) || (this.baseURL.trim().equals(""))) { + return "file:."; + } else { + return this.baseURL; + } + } + + /** + * Get an input stream for a reference. + * Temporary solution until API better. + * @param uri URI to access + * @return InputStream for accessing the resource. + * @throws IOException in case of an I/O problem + */ + public InputStream getStream(String uri) throws IOException { + return null; + } + + /** + * Returns the conversion factor from pixel units to millimeters. This + * depends on the desired reolution. + * @return float conversion factor + */ + public float getPixelUnitToMillimeter() { + return 0.35277777777777777778f; + } + + /** + * If to create hot links to footnotes and before floats. + * @return True if hot links dhould be created + */ + public boolean linkToFootnotes() { + return true; + } + + /** + * Set the default xml handler for the given mime type. + * @param mime MIME type + * @param handler XMLHandler to use + */ + public void setDefaultXMLHandler(String mime, XMLHandler handler) { + defaults.put(mime, handler); + } + + /** + * Add an xml handler for the given mime type and xml namespace. + * @param mime MIME type + * @param ns Namespace URI + * @param handler XMLHandler to use + */ + public void addXMLHandler(String mime, String ns, XMLHandler handler) { + Map mh = (Map) handlers.get(mime); + if (mh == null) { + mh = new java.util.HashMap(); + handlers.put(mime, mh); + } + mh.put(ns, handler); + } + + /** + * Render the xml document with the given xml namespace. + * The Render Context is by the handle to render into the current + * rendering target. + * @param ctx rendering context + * @param doc DOM Document containing the source document + * @param namespace Namespace URI of the document + */ + public void renderXML(RendererContext ctx, Document doc, + String namespace) { + String mime = ctx.getMimeType(); + Map mh = (Map) handlers.get(mime); + XMLHandler handler = null; + if (mh != null) { + handler = (XMLHandler) mh.get(namespace); + } + if (handler == null) { + handler = (XMLHandler) defaults.get(mime); + } + if (handler != null) { + try { + handler.handleXML(ctx, doc, namespace); + } catch (Throwable t) { + // could not handle document + getLogger().error("Some XML content will be ignored. " + + "Could not render XML", t); + } + } else { + // no handler found for document + getLogger().warn("Some XML content will be ignored. " + + "No handler defined for XML: " + namespace); + } + } +} + diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java new file mode 100644 index 000000000..c9a840d54 --- /dev/null +++ b/src/java/org/apache/fop/fo/FObj.java @@ -0,0 +1,376 @@ +/* + * $Id: FObj.java,v 1.40 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.Iterator; +import java.util.ListIterator; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Set; +import java.util.Map; +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.fo.properties.FOPropertyMapping; +import org.apache.fop.fo.flow.Marker; + +/** + * base class for representation of formatting objects and their processing + */ +public class FObj extends FONode { + private static final String FO_URI = "http://www.w3.org/1999/XSL/Format"; + + /** + * Static property list builder that converts xml attributes + * into fo properties. This is static since the underlying + * property mappings for fo are also static. + */ + protected static PropertyListBuilder plb = null; + + /** + * Structure handler used to notify structure events + * such as start end element. + */ + protected StructureHandler structHandler; + + /** + * Formatting properties for this fo element. + */ + public PropertyList properties; + + /** + * Property manager for handler some common properties. + */ + protected PropertyManager propMgr; + + /** + * Id of this fo element of null if no id. + */ + protected String id = null; + + /** + * The children of this node. + */ + protected ArrayList children = null; + + /** + * Markers added to this element. + */ + protected Map markers = null; + + /** + * Create a new formatting object. + * All formatting object classes extend this class. + * + * @param parent the parent node + */ + public FObj(FONode parent) { + super(parent); + } + + /** + * Set the name of this element. + * The prepends "fo:" to the name to indicate it is in the fo namespace. + * + * @param str the xml element name + */ + public void setName(String str) { + name = "fo:" + str; + } + + protected PropertyListBuilder getListBuilder() { + if (plb == null) { + plb = new PropertyListBuilder(); + plb.addList(FOPropertyMapping.getGenericMappings()); + + for (Iterator iter = + FOPropertyMapping.getElementMappings().iterator(); + iter.hasNext();) { + String elem = (String) iter.next(); + plb.addElementList(elem, + FOPropertyMapping.getElementMapping(elem)); + } + } + return plb; + } + + /** + * Handle the attributes for this element. + * The attributes must be used immediately as the sax attributes + * will be altered for the next element. + */ + public void handleAttrs(Attributes attlist) throws FOPException { + FONode par = parent; + while (par != null && !(par instanceof FObj)) { + par = par.parent; + } + PropertyList props = null; + if (par != null) { + props = ((FObj) par).properties; + } + properties = getListBuilder().makeList(FO_URI, name, attlist, props, + (FObj) par); + properties.setFObj(this); + this.propMgr = makePropertyManager(properties); + setWritingMode(); + } + + protected PropertyManager makePropertyManager( + PropertyList propertyList) { + return new PropertyManager(propertyList); + } + + /** + * Add the child to this object. + * + * @param child the child node to add + */ + protected void addChild(FONode child) { + if (containsMarkers() && child.isMarker()) { + addMarker((Marker)child); + } else { + if (children == null) { + children = new ArrayList(); + } + children.add(child); + } + } + + /** + * Set the structure handler for handling structure events. + * + * @param st the structure handler + */ + public void setStructHandler(StructureHandler st) { + structHandler = st; + } + + /** + * lets outside sources access the property list + * first used by PageNumberCitation to find the "id" property + * @param name - the name of the desired property to obtain + * @return the property + */ + public Property getProperty(String name) { + return (properties.get(name)); + } + + /** + * Setup the id for this formatting object. + * Most formatting objects can have an id that can be referenced. + * This methods checks that the id isn't already used by another + * fo and sets the id attribute of this object. + */ + protected void setupID() { + Property prop = this.properties.get("id"); + if (prop != null) { + String str = prop.getString(); + if (str != null && !str.equals("")) { + Set idrefs = structHandler.getIDReferences(); + if (!idrefs.contains(str)) { + id = str; + idrefs.add(id); + } else { + getLogger().warn("duplicate id:" + str + " ignored"); + } + } + } + } + + /** + * Get the id string for this formatting object. + * This will be unique for the fo document. + * + * @return the id string or null if not set + */ + public String getID() { + return id; + } + + /** + * Check if this formatting object generates reference areas. + * + * @return true if generates reference areas + */ + public boolean generatesReferenceAreas() { + return false; + } + + /** + * Check if this formatting object generates inline areas. + * + * @return true if generates inline areas + */ + public boolean generatesInlineAreas() { + return true; + } + + /** + * Check if this formatting object may contain markers. + * + * @return true if this can contian markers + */ + protected boolean containsMarkers() { + return false; + } + + /** + * Set writing mode for this FO. + * Find nearest ancestor, including self, which generates + * reference areas and use the value of its writing-mode property. + * If no such ancestor is found, use the value on the root FO. + */ + protected void setWritingMode() { + FObj p; + FONode parent; + for (p = this; !p.generatesReferenceAreas() + && (parent = p.getParent()) != null + && (parent instanceof FObj); p = (FObj) parent) { + } + this.properties.setWritingMode( + p.getProperty("writing-mode").getEnum()); + } + + /** + * Return a LayoutManager responsible for laying out this FObj's content. + * Must override in subclasses if their content can be laid out. + * @param list the list to add the layout manager(s) to + */ + public void addLayoutManager(List list) { + } + + /** + * Return an iterator over all the children of this FObj. + * @return A ListIterator. + */ + public ListIterator getChildren() { + if (children != null) { + return children.listIterator(); + } + return null; + } + + /** + * Return an iterator over the object's children starting + * at the pased node. + * @param childNode First node in the iterator + * @return A ListIterator or null if childNode isn't a child of + * this FObj. + */ + public ListIterator getChildren(FONode childNode) { + if (children != null) { + int i = children.indexOf(childNode); + if (i >= 0) { + return children.listIterator(i); + } + } + return null; + } + + /** + * Add the marker to this formatting object. + * If this object can contain markers it checks that the marker + * has a unique class-name for this object and that it is + * the first child. + */ + public void addMarker(Marker marker) { + String mcname = marker.getMarkerClassName(); + if (children != null) { + // check for empty children + for (Iterator iter = children.iterator(); iter.hasNext();) { + FONode node = (FONode)iter.next(); + if (node instanceof FOText) { + FOText text = (FOText)node; + if (text.willCreateArea()) { + getLogger().error("fo:marker must be an initial child: " + mcname); + return; + } else { + iter.remove(); + } + } else { + getLogger().error("fo:marker must be an initial child: " + mcname); + return; + } + } + } + if (markers == null) { + markers = new HashMap(); + } + if (!markers.containsKey(mcname)) { + markers.put(mcname, marker); + } else { + getLogger().error("fo:marker 'marker-class-name' " + + "must be unique for same parent: " + mcname); + } + } + + public boolean hasMarkers() { + return markers != null && !markers.isEmpty(); + } + + public Map getMarkers() { + return markers; + } + + /** + * lets layout managers access FO properties via PropertyManager + * @return the property manager for this FO + */ + public PropertyManager getPropertyManager() { + return this.propMgr; + } + +} + diff --git a/src/java/org/apache/fop/fo/FObjMixed.java b/src/java/org/apache/fop/fo/FObjMixed.java new file mode 100644 index 000000000..4800895b1 --- /dev/null +++ b/src/java/org/apache/fop/fo/FObjMixed.java @@ -0,0 +1,113 @@ +/* + * $Id: FObjMixed.java,v 1.33 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.layout.FontInfo; +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.layoutmgr.InlineStackingLayoutManager; +import org.apache.fop.layoutmgr.LMiter; + +import java.util.List; + +/** + * base class for representation of mixed content formatting objects + * and their processing + */ +public class FObjMixed extends FObj { + protected TextInfo textInfo = null; + protected FontInfo fontInfo = null; + + public FObjMixed(FONode parent) { + super(parent); + } + + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + fontInfo = st.getFontInfo(); + } + + public void addLayoutManager(List lms) { + if (children != null) { + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setLMiter(new LMiter(children.listIterator())); + lms.add(lm); + } + } + + protected void addCharacters(char data[], int start, int length) { + if (textInfo == null) { + // Really only need one of these, but need to get fontInfo + // stored in propMgr for later use. + propMgr.setFontInfo(fontInfo); + textInfo = propMgr.getTextLayoutProps(fontInfo); + } + + FOText ft = new FOText(data, start, length, textInfo); + ft.setUserAgent(userAgent); + ft.setStructHandler(structHandler); + addChild(ft); + } + + public void setup() { + if (this.properties != null) { + setupID(); + } + } + + public CharIterator charIterator() { + return new RecursiveCharIterator(this); + } + +} + diff --git a/src/java/org/apache/fop/fo/GenericShorthandParser.java b/src/java/org/apache/fop/fo/GenericShorthandParser.java new file mode 100644 index 000000000..72dbb0aa3 --- /dev/null +++ b/src/java/org/apache/fop/fo/GenericShorthandParser.java @@ -0,0 +1,107 @@ +/* + * $Id: GenericShorthandParser.java,v 1.4 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.Vector; +import java.util.Enumeration; + +public class GenericShorthandParser implements ShorthandParser { + + protected Vector list; // Vector of Property objects + + public GenericShorthandParser(ListProperty listprop) { + this.list = listprop.getList(); + } + + protected Property getElement(int index) { + if (list.size() > index) { + return (Property)list.elementAt(index); + } else { + return null; + } + } + + protected int count() { + return list.size(); + } + + // Stores 1 to 3 values for border width, style, color + // Used for: border, border-top, border-right etc + public Property getValueForProperty(String propName, + Property.Maker maker, + PropertyList propertyList) { + Property prop = null; + // Check for keyword "inherit" + if (count() == 1) { + String sval = ((Property)list.elementAt(0)).getString(); + if (sval != null && sval.equals("inherit")) { + return propertyList.getFromParent(propName); + } + } + return convertValueForProperty(propName, maker, propertyList); + } + + + protected Property convertValueForProperty(String propName, + Property.Maker maker, + PropertyList propertyList) { + Property prop = null; + // Try each of the stored values in turn + Enumeration eprop = list.elements(); + while (eprop.hasMoreElements() && prop == null) { + Property p = (Property)eprop.nextElement(); + prop = maker.convertShorthandProperty(propertyList, p, null); + } + return prop; + } + +} + diff --git a/src/java/org/apache/fop/fo/InlineCharIterator.java b/src/java/org/apache/fop/fo/InlineCharIterator.java new file mode 100644 index 000000000..bcdc37d6c --- /dev/null +++ b/src/java/org/apache/fop/fo/InlineCharIterator.java @@ -0,0 +1,106 @@ +/* + * $Id: InlineCharIterator.java,v 1.4 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.util.CharUtilities; +import java.util.NoSuchElementException; + + +public class InlineCharIterator extends RecursiveCharIterator { + private boolean bStartBoundary = false; + private boolean bEndBoundary = false; + + public InlineCharIterator(FObj fobj, BorderAndPadding bap) { + super(fobj); + checkBoundaries(bap); + } + + + private void checkBoundaries(BorderAndPadding bap) { + // TODO! use start and end in BAP!! + bStartBoundary = (bap.getBorderLeftWidth(false) > 0 + || bap.getPaddingLeft(false) > 0); + bEndBoundary = (bap.getBorderRightWidth(false) > 0 + || bap.getPaddingRight(false) > 0); + } + + public boolean hasNext() { + if (bStartBoundary) { + return true; + } + return (super.hasNext() || bEndBoundary); + /* If super.hasNext() returns false, + * we return true if we are going to return a "boundary" signal + * else false. + */ + } + + public char nextChar() throws NoSuchElementException { + if (bStartBoundary) { + bStartBoundary = false; + return CharUtilities.CODE_EOT; + } + try { + return super.nextChar(); + } catch (NoSuchElementException e) { + // Underlying has nothing more to return + // Check end boundary char + if (bEndBoundary) { + bEndBoundary = false; + return CharUtilities.CODE_EOT; + } else { + throw e; + } + } + } +} + diff --git a/src/java/org/apache/fop/fo/KeepProperty.java b/src/java/org/apache/fop/fo/KeepProperty.java new file mode 100644 index 000000000..3ac7692fd --- /dev/null +++ b/src/java/org/apache/fop/fo/KeepProperty.java @@ -0,0 +1,79 @@ +/* + * $Id: KeepProperty.java,v 1.3 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.Keep; + +public class KeepProperty extends Property { + + public static class Maker extends Property.Maker { + + protected Maker(String name) { + super(name); + } + + } + + private Keep keep; + + public KeepProperty(Keep keep) { + this.keep = keep; + } + + public Keep getKeep() { + return this.keep; + } + + public Object getObject() { + return this.keep; + } + +} diff --git a/src/java/org/apache/fop/fo/LengthPairProperty.java b/src/java/org/apache/fop/fo/LengthPairProperty.java new file mode 100644 index 000000000..8b0ff539e --- /dev/null +++ b/src/java/org/apache/fop/fo/LengthPairProperty.java @@ -0,0 +1,79 @@ +/* + * $Id: LengthPairProperty.java,v 1.3 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.LengthPair; + +public class LengthPairProperty extends Property { + + public static class Maker extends LengthProperty.Maker { + + protected Maker(String name) { + super(name); + } + + } + + private LengthPair lengthPair; + + public LengthPairProperty(LengthPair lengthPair) { + this.lengthPair = lengthPair; + } + + public LengthPair getLengthPair() { + return this.lengthPair; + } + + public Object getObject() { + return this.lengthPair; + } + +} diff --git a/src/java/org/apache/fop/fo/LengthProperty.java b/src/java/org/apache/fop/fo/LengthProperty.java new file mode 100644 index 000000000..2bdeed108 --- /dev/null +++ b/src/java/org/apache/fop/fo/LengthProperty.java @@ -0,0 +1,130 @@ +/* + * $Id: LengthProperty.java,v 1.7 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.AutoLength; +import org.apache.fop.fo.expr.Numeric; +import org.apache.fop.apps.FOPException; + +public class LengthProperty extends Property { + + public static class Maker extends Property.Maker { + + public /* protected */ Maker(String name) { + super(name); + } + + /** + * protected Property checkPropertyKeywords(String value) { + * if (isAutoLengthAllowed() && value.equals("auto")) { + * return new LengthProperty(Length.AUTO); + * } + * return null; + * } + */ + + protected boolean isAutoLengthAllowed() { + return false; + } + + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) throws FOPException { + if (isAutoLengthAllowed()) { + String pval = p.getString(); + if (pval != null && pval.equals("auto")) { + return new LengthProperty(new AutoLength()); + } + } + if (p instanceof LengthProperty) { + return p; + } + Length val = p.getLength(); + if (val != null) { + return new LengthProperty(val); + } + return convertPropertyDatatype(p, propertyList, fo); + } + + } + + /* + * public static Property.Maker maker(String prop) { + * return new Maker(prop); + * } + */ + + /** + * This object may be also be a subclass of Length, such + * as PercentLength, TableColLength. + */ + private Length length; + + public LengthProperty(Length length) { + this.length = length; + // System.err.println("Set LengthProperty: " + length.toString()); + } + + public Numeric getNumeric() { + return length.asNumeric() ; + } + + public Length getLength() { + return this.length; + } + + public Object getObject() { + return this.length; + } + +} + diff --git a/src/java/org/apache/fop/fo/LengthRangeProperty.java b/src/java/org/apache/fop/fo/LengthRangeProperty.java new file mode 100644 index 000000000..d157b0d74 --- /dev/null +++ b/src/java/org/apache/fop/fo/LengthRangeProperty.java @@ -0,0 +1,79 @@ +/* + * $Id: LengthRangeProperty.java,v 1.5 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.LengthRange; + +public class LengthRangeProperty extends Property { + + public static class Maker extends LengthProperty.Maker { + + protected Maker(String name) { + super(name); + } + + } + + private LengthRange lengthRange; + + public LengthRangeProperty(LengthRange lengthRange) { + this.lengthRange = lengthRange; + } + + public LengthRange getLengthRange() { + return this.lengthRange; + } + + public Object getObject() { + return this.lengthRange; + } + +} diff --git a/src/java/org/apache/fop/fo/ListProperty.java b/src/java/org/apache/fop/fo/ListProperty.java new file mode 100644 index 000000000..c9b2008c8 --- /dev/null +++ b/src/java/org/apache/fop/fo/ListProperty.java @@ -0,0 +1,93 @@ +/* + * $Id: ListProperty.java,v 1.3 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.Vector; + +public class ListProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String name) { + super(name); + } + + public Property convertProperty(Property p, + PropertyList propertyList, FObj fo) { + if (p instanceof ListProperty) { + return p; + } else { + return new ListProperty(p); + } + } + + } + + protected Vector list; + + public ListProperty(Property prop) { + list = new Vector(); + list.addElement(prop); + } + + public void addProperty(Property prop) { + list.addElement(prop); + } + + public Vector getList() { + return list; + } + + public Object getObject() { + return list; + } + +} diff --git a/src/java/org/apache/fop/fo/NumberProperty.java b/src/java/org/apache/fop/fo/NumberProperty.java new file mode 100644 index 000000000..ea228f04f --- /dev/null +++ b/src/java/org/apache/fop/fo/NumberProperty.java @@ -0,0 +1,119 @@ +/* + * $Id: NumberProperty.java,v 1.6 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.expr.Numeric; + +public class NumberProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String propName) { + super(propName); + } + + public Property convertProperty(Property p, + PropertyList propertyList, FObj fo) { + if (p instanceof NumberProperty) { + return p; + } + Number val = p.getNumber(); + if (val != null) { + return new NumberProperty(val); + } + return convertPropertyDatatype(p, propertyList, fo); + } + + } + + private Number number; + + public NumberProperty(Number num) { + this.number = num; + } + + public NumberProperty(double num) { + this.number = new Double(num); + } + + public NumberProperty(int num) { + this.number = new Integer(num); + } + + public Number getNumber() { + return this.number; + } + + /** + * public Double getDouble() { + * return new Double(this.number.doubleValue()); + * } + * public Integer getInteger() { + * return new Integer(this.number.intValue()); + * } + */ + + public Object getObject() { + return this.number; + } + + public Numeric getNumeric() { + return new Numeric(this.number); + } + + public ColorType getColorType() { + // Convert numeric value to color ??? + // Convert to hexadecimal and then try to make it into a color? + return new ColorType((float)0.0, (float)0.0, (float)0.0); + } + +} diff --git a/src/java/org/apache/fop/fo/OneCharIterator.java b/src/java/org/apache/fop/fo/OneCharIterator.java new file mode 100644 index 000000000..4a618e020 --- /dev/null +++ b/src/java/org/apache/fop/fo/OneCharIterator.java @@ -0,0 +1,79 @@ +/* + * $Id: OneCharIterator.java,v 1.4 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.NoSuchElementException; + + +public class OneCharIterator extends AbstractCharIterator { + + private boolean bFirst = true; + private char charCode; + + public OneCharIterator(char c) { + this.charCode = c; + } + + public boolean hasNext() { + return bFirst; + } + + public char nextChar() throws NoSuchElementException { + if (bFirst) { + bFirst = false; + return charCode; + } else { + throw new NoSuchElementException(); + } + } + +} + diff --git a/src/java/org/apache/fop/fo/Property.java b/src/java/org/apache/fop/fo/Property.java new file mode 100644 index 000000000..0791ab967 --- /dev/null +++ b/src/java/org/apache/fop/fo/Property.java @@ -0,0 +1,490 @@ +/* + * $Id: Property.java,v 1.22 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.CondLength; +import org.apache.fop.datatypes.Keep; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthPair; +import org.apache.fop.datatypes.LengthRange; +import org.apache.fop.datatypes.PercentBase; +import org.apache.fop.datatypes.Space; +import org.apache.fop.fo.expr.Numeric; +import org.apache.fop.fo.expr.PropertyParser; +import org.apache.fop.fo.expr.PropertyInfo; +import org.apache.fop.apps.FOPException; +import java.util.Vector; + +public class Property { + + public static class Maker { + private static final String UNKNOWN = "UNKNOWN"; + private String propName; + + /** + * Return the name of the property whose value is being set. + */ + protected String getPropName() { + return propName; + } + + /** + * Construct an instance of a Property.Maker for the given property. + * @param propName The name of the property to be made. + */ + protected Maker(String propName) { + this.propName = propName; + } + + /** + * Construct an instance of a Property.Maker. + * Note: the property name is set to "UNKNOWN". + */ + protected Maker() { + this.propName = UNKNOWN; + } + + + /** + * Default implementation of isInherited. + * @return A boolean indicating whether this property is inherited. + */ + public boolean isInherited() { + return false; + } + + /** + * Return a boolean indicating whether this property inherits the + * "specified" value rather than the "computed" value. The default is + * to inherit the "computed" value. + * @return If true, property inherits the value specified. + */ + public boolean inheritsSpecified() { + return false; + } + + + /** + * Return an object implementing the PercentBase interface. + * This is used to handle properties specified as a percentage of + * some "base length", such as the content width of their containing + * box. + * Overridden by subclasses which allow percent specifications. See + * the documentation on properties.xsl for details. + */ + public PercentBase getPercentBase(FObj fo, PropertyList pl) { + return null; + } + + /** + * Return a Maker object which is used to set the values on components + * of compound property types, such as "space". + * Overridden by property maker subclasses which handle + * compound properties. + * @param subprop The name of the component for which a Maker is to + * returned, for example "optimum", if the FO attribute is + * space.optimum='10pt'. + */ + protected Maker getSubpropMaker(String subprop) { + return null; + } + + /** + * Return a property value for the given component of a compound + * property. + * @param p A property value for a compound property type such as + * SpaceProperty. + * @param subprop The name of the component whose value is to be + * returned. + * NOTE: this is only to ease porting when calls are made to + * PropertyList.get() using a component name of a compound property, + * such as get("space.optimum"). The recommended technique is: + * get("space").getOptimum(). + * Overridden by property maker subclasses which handle + * compound properties. + */ + public Property getSubpropValue(Property p, String subprop) { + return null; + } + + /** + * Return a property value for a compound property. If the property + * value is already partially initialized, this method will modify it. + * @param baseProp The Property object representing the compound property, + * such as SpaceProperty. + * @param partName The name of the component whose value is specified. + * @param propertyList The propertyList being built. + * @param fo The FO whose properties are being set. + * @return A compound property object. + */ + public Property make(Property baseProp, String partName, + PropertyList propertyList, String value, + FObj fo) throws FOPException { + if (baseProp == null) { + baseProp = makeCompound(propertyList, fo); + } + Maker spMaker = getSubpropMaker(partName); + if (spMaker != null) { + Property p = spMaker.make(propertyList, value, fo); + if (p != null) { + return setSubprop(baseProp, partName, p); + } + } else { + //getLogger().error("compound property component " + // + partName + " unknown."); + } + return baseProp; + } + + /** + * Set a component in a compound property and return the modified + * compound property object. + * This default implementation returns the original base property + * without modifying it. + * It is overridden by property maker subclasses which handle + * compound properties. + * @param baseProp The Property object representing the compound property, + * such as SpaceProperty. + * @param partName The name of the component whose value is specified. + * @param subProp A Property object holding the specified value of the + * component to be set. + * @return The modified compound property object. + */ + protected Property setSubprop(Property baseProp, String partName, + Property subProp) { + return baseProp; + } + + /** + * Create a Property object from an attribute specification. + * @param propertyList The PropertyList object being built for this FO. + * @param value The attribute value. + * @param fo The current FO whose properties are being set. + * @return The initialized Property object. + */ + public Property make(PropertyList propertyList, String value, + FObj fo) throws FOPException { + try { + Property pret = null; + String pvalue = value; + pret = checkEnumValues(value); + if (pret == null) { + /* Check for keyword shorthand values to be substituted. */ + pvalue = checkValueKeywords(value); + // Override parsePropertyValue in each subclass of Property.Maker + Property p = PropertyParser.parse(pvalue, + new PropertyInfo(this, + propertyList, fo)); + pret = convertProperty(p, propertyList, fo); + } else if (isCompoundMaker()) { + pret = convertProperty(pret, propertyList, fo); + } + if (pret == null) { + throw new org.apache.fop.fo.expr.PropertyException("No conversion defined"); + } else if (inheritsSpecified()) { + pret.setSpecifiedValue(pvalue); + } + return pret; + } catch (org.apache.fop.fo.expr.PropertyException propEx) { + throw new FOPException("Error in " + propName + + " property value '" + value + "': " + + propEx); + } + } + + public Property convertShorthandProperty(PropertyList propertyList, + Property prop, FObj fo) { + Property pret = null; + try { + pret = convertProperty(prop, propertyList, fo); + if (pret == null) { + // If value is a name token, may be keyword or Enum + String sval = prop.getNCname(); + if (sval != null) { + // System.err.println("Convert shorthand ncname " + sval); + pret = checkEnumValues(sval); + if (pret == null) { + /* Check for keyword shorthand values to be substituted. */ + String pvalue = checkValueKeywords(sval); + if (!pvalue.equals(sval)) { + // System.err.println("Convert shorthand keyword" + pvalue); + // Substituted a value: must parse it + Property p = + PropertyParser.parse(pvalue, + new PropertyInfo(this, + propertyList, + fo)); + pret = convertProperty(p, propertyList, fo); + } + } + } + } + } catch (FOPException e) { + + //getLogger().error("convertShorthandProperty caught FOPException " + // + e); + } catch (org.apache.fop.fo.expr.PropertyException propEx) { + //getLogger().error("convertShorthandProperty caught PropertyException " + // + propEx); + } + if (pret != null) { + /* + * System.err.println("Return shorthand value " + pret.getString() + + * " for " + getPropName()); + */ + } + return pret; + } + + protected boolean isCompoundMaker() { + return false; + } + + public Property checkEnumValues(String value) { + return null; + } + + /** + * Return a String to be parsed if the passed value corresponds to + * a keyword which can be parsed and used to initialize the property. + * For example, the border-width family of properties can have the + * initializers "thin", "medium", or "thick". The foproperties.xml + * file specifies a length value equivalent for these keywords, + * such as "0.5pt" for "thin". These values are considered parseable, + * since the Length object is no longer responsible for parsing + * unit expresssions. + * @param value The string value of property attribute. + * @return A String containging a parseable equivalent or null if + * the passed value isn't a keyword initializer for this Property. + */ + protected String checkValueKeywords(String value) { + return value; + } + + /** + * Return a Property object based on the passed Property object. + * This method is called if the Property object built by the parser + * isn't the right type for this property. + * It is overridden by subclasses when the property specification in + * foproperties.xml specifies conversion rules. + * @param p The Property object return by the expression parser + * @param propertyList The PropertyList object being built for this FO. + * @param fo The current FO whose properties are being set. + * @return A Property of the correct type or null if the parsed value + * can't be converted to the correct type. + */ + public Property convertProperty(Property p, + PropertyList propertyList, + FObj fo) throws FOPException { + return null; + } + + protected Property convertPropertyDatatype(Property p, + PropertyList propertyList, + FObj fo) { + return null; + } + + /** + * Return a Property object representing the initial value. + * @param propertyList The PropertyList object being built for this FO. + */ + public Property make(PropertyList propertyList) throws FOPException { + return null; + } + + /** + * Return a Property object representing the initial value. + * @param propertyList The PropertyList object being built for this FO. + * @param parentFO The parent FO for the FO whose property is being made. + * @return a Property subclass object holding a "compound" property object + * initialized to the default values for each component. + */ + protected Property makeCompound(PropertyList propertyList, + FObj parentFO) throws FOPException { + return null; + } + + /** + * Return a Property object representing the value of this property, + * based on other property values for this FO. + * A special case is properties which inherit the specified value, + * rather than the computed value. + * @param propertyList The PropertyList for the FO. + * @return Property A computed Property value or null if no rules + * are specified (in foproperties.xml) to compute the value. + */ + public Property compute(PropertyList propertyList) + throws FOPException { + if (inheritsSpecified()) { + // recalculate based on last specified value + // Climb up propertylist and find last spec'd value + // NEED PROPNAME!!! get from Maker + Property specProp = + propertyList.getNearestSpecified(propName); + if (specProp != null) { + // Only need to do this if the value is relative!!! + String specVal = specProp.getSpecifiedValue(); + if (specVal != null) { + try { + return make(propertyList, specVal, + propertyList.getParentFObj()); + } catch (FOPException e) { + //getLogger()error("Error computing property value for " + // + propName + " from " + // + specVal); + return null; + } + } + } + } + return null; // standard + } + + public boolean isCorrespondingForced(PropertyList propertyList) { + return false; + } + + public Property getShorthand(PropertyList propertyList) { + return null; + } + + } // end of nested Maker class + + /** + * The original specified value for properties which inherit + * specified values. + */ + private String specVal; + + /** + * Set the original value specified for the property attribute. + * @param specVal The specified value. + */ + public void setSpecifiedValue(String specVal) { + this.specVal = specVal; + } + + /** + * Return the original value specified for the property attribute. + * @return The specified value as a String. + */ + public String getSpecifiedValue() { + return specVal; + } + + /** + * Accessor functions for all possible Property datatypes + */ + public Length getLength() { + return null; + } + + public ColorType getColorType() { + return null; + } + + public CondLength getCondLength() { + return null; + } + + public LengthRange getLengthRange() { + return null; + } + + public LengthPair getLengthPair() { + return null; + } + + public Space getSpace() { + return null; + } + + public Keep getKeep() { + return null; + } + + public int getEnum() { + return 0; + } + + public char getCharacter() { + return 0; + } + + public Vector getList() { + return null; + } // List of Property objects + + public Number getNumber() { + return null; + } + + // Classes used when evaluating property expressions + public Numeric getNumeric() { + return null; + } + + public String getNCname() { + return null; + } + + public Object getObject() { + return null; + } + + public String getString() { + Object o = getObject(); + return (o == null) ? null : o.toString(); + } + +} diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java new file mode 100644 index 000000000..eab6969e0 --- /dev/null +++ b/src/java/org/apache/fop/fo/PropertyList.java @@ -0,0 +1,416 @@ +/* + * $Id: PropertyList.java,v 1.20 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.HashMap; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.apps.FOPException; + +public class PropertyList extends HashMap { + + private byte[] wmtable = null; // writing-mode values + public static final int LEFT = 0; + public static final int RIGHT = 1; + public static final int TOP = 2; + public static final int BOTTOM = 3; + public static final int HEIGHT = 4; + public static final int WIDTH = 5; + + public static final int START = 0; + public static final int END = 1; + public static final int BEFORE = 2; + public static final int AFTER = 3; + public static final int BLOCKPROGDIM = 4; + public static final int INLINEPROGDIM = 5; + + private static final String[] ABS_NAMES = new String[] { + "left", "right", "top", "bottom", "height", "width" + }; + + private static final String[] REL_NAMES = new String[] { + "start", "end", "before", "after", "block-progression-dimension", + "inline-progression-dimension" + }; + + private static final HashMap WRITING_MODE_TABLES = new HashMap(4); + { + WRITING_MODE_TABLES.put(new Integer(WritingMode.LR_TB), /* lr-tb */ + new byte[] { + START, END, BEFORE, AFTER, BLOCKPROGDIM, INLINEPROGDIM + }); + WRITING_MODE_TABLES.put(new Integer(WritingMode.RL_TB), /* rl-tb */ + new byte[] { + END, START, BEFORE, AFTER, BLOCKPROGDIM, INLINEPROGDIM + }); + WRITING_MODE_TABLES.put(new Integer(WritingMode.TB_RL), /* tb-rl */ + new byte[] { + AFTER, BEFORE, START, END, INLINEPROGDIM, BLOCKPROGDIM + }); + } + + private PropertyListBuilder builder; + private PropertyList parentPropertyList = null; + private String namespace = ""; + private String element = ""; + private FObj fobj = null; + + public PropertyList(PropertyList parentPropertyList, String space, + String el) { + this.parentPropertyList = parentPropertyList; + this.namespace = space; + this.element = el; + } + + public void setFObj(FObj fobj) { + this.fobj = fobj; + } + + public FObj getFObj() { + return this.fobj; + } + + public FObj getParentFObj() { + if (parentPropertyList != null) { + return parentPropertyList.getFObj(); + } else { + return null; + } + } + + /** + * Return the value explicitly specified on this FO. + * @param propertyName The name of the property whose value is desired. + * It may be a compound name, such as space-before.optimum. + * @return The value if the property is explicitly set or set by + * a shorthand property, otherwise null. + */ + public Property getExplicitOrShorthand(String propertyName) { + /* Handle request for one part of a compound property */ + int sepchar = propertyName.indexOf('.'); + String baseName; + if (sepchar > -1) { + baseName = propertyName.substring(0, sepchar); + } else { + baseName = propertyName; + } + Property p = getExplicitBaseProp(baseName); + if (p == null) { + p = builder.getShorthand(this, namespace, element, baseName); + } + if (p != null && sepchar > -1) { + return builder.getSubpropValue(namespace, element, baseName, p, + propertyName.substring(sepchar + + 1)); + } + return p; + } + + /** + * Return the value explicitly specified on this FO. + * @param propertyName The name of the property whose value is desired. + * It may be a compound name, such as space-before.optimum. + * @return The value if the property is explicitly set, otherwise null. + */ + public Property getExplicit(String propertyName) { + /* Handle request for one part of a compound property */ + int sepchar = propertyName.indexOf('.'); + if (sepchar > -1) { + String baseName = propertyName.substring(0, sepchar); + Property p = getExplicitBaseProp(baseName); + if (p != null) { + return this.builder.getSubpropValue(namespace, element, + baseName, p, + propertyName.substring(sepchar + + 1)); + } else { + return null; + } + } + return (Property)super.get(propertyName); + } + + /** + * Return the value explicitly specified on this FO. + * @param propertyName The name of the base property whose value is desired. + * @return The value if the property is explicitly set, otherwise null. + */ + public Property getExplicitBaseProp(String propertyName) { + return (Property)super.get(propertyName); + } + + /** + * Return the value of this property inherited by this FO. + * Implements the inherited-property-value function. + * The property must be inheritable! + * @param propertyName The name of the property whose value is desired. + * @return The inherited value, otherwise null. + */ + public Property getInherited(String propertyName) { + if (builder != null) { + if (parentPropertyList != null + && builder.isInherited(namespace, element, + propertyName)) { + return parentPropertyList.get(propertyName); + } else { + // return the "initial" value + try { + return builder.makeProperty(this, namespace, element, + propertyName); + } catch (org.apache.fop.apps.FOPException e) { + //log.error("Exception in getInherited(): property=" + // + propertyName + " : " + e); + } + } + } + return null; // No builder or exception in makeProperty! + } + + /* + * If the property is a relative property with a corresponding absolute + * value specified, the absolute value is used. This is also true of + * the inheritance priority (I think...) + * If the property is an "absolute" property and it isn't specified, then + * we try to compute it from the corresponding relative property: this + * happends in computeProperty. + */ + private Property findProperty(String propertyName, boolean bTryInherit) { + Property p = null; + if (builder.isCorrespondingForced(this, namespace, element, + propertyName)) { + p = builder.computeProperty(this, namespace, element, + propertyName); + } else { + p = getExplicitBaseProp(propertyName); + if (p == null) { + p = this.builder.computeProperty(this, namespace, element, + propertyName); + } + if (p == null) { // check for shorthand specification + p = builder.getShorthand(this, namespace, element, + propertyName); + } + if (p == null + && bTryInherit) { // else inherit (if has parent and is inheritable) + if (this.parentPropertyList != null + && builder.isInherited(namespace, element, + propertyName)) { + p = parentPropertyList.findProperty(propertyName, true); + } + } + } + return p; + } + + + /** + * Return the property on the current FlowObject if it is specified, or if a + * corresponding property is specified. If neither is specified, it returns null. + */ + public Property getSpecified(String propertyName) { + return get(propertyName, false, false); + } + + + /** + * Return the property on the current FlowObject. If it isn't set explicitly, + * this will try to compute it based on other properties, or if it is + * inheritable, to return the inherited value. If all else fails, it returns + * the default value. + */ + public Property get(String propertyName) { + return get(propertyName, true, true); + } + + /** + * Return the property on the current FlowObject. Depending on the passed flags, + * this will try to compute it based on other properties, or if it is + * inheritable, to return the inherited value. If all else fails, it returns + * the default value. + */ + private Property get(String propertyName, boolean bTryInherit, + boolean bTryDefault) { + + if (builder == null) { + //log.error("OH OH, builder has not been set"); + } + /* Handle request for one part of a compound property */ + int sepchar = propertyName.indexOf('.'); + String subpropName = null; + if (sepchar > -1) { + subpropName = propertyName.substring(sepchar + 1); + propertyName = propertyName.substring(0, sepchar); + } + + Property p = findProperty(propertyName, bTryInherit); + if (p == null && bTryDefault) { // default value for this FO! + try { + p = this.builder.makeProperty(this, namespace, element, + propertyName); + } catch (FOPException e) { + // don't know what to do here + } + } + + // if value is inherit then get computed value from + // parent + if (p != null && "inherit".equals(p.getSpecifiedValue())) { + if (this.parentPropertyList != null) { + p = parentPropertyList.get(propertyName, true, false); + } + } + + if (subpropName != null && p != null) { + return this.builder.getSubpropValue(namespace, element, + propertyName, p, subpropName); + } else { + return p; + } + } + + public void setBuilder(PropertyListBuilder builder) { + this.builder = builder; + } + + public String getNameSpace() { + return namespace; + } + + public String getElement() { + return element; + } + + /** + * Return the "nearest" specified value for the given property. + * Implements the from-nearest-specified-value function. + * @param propertyName The name of the property whose value is desired. + * @return The computed value if the property is explicitly set on some + * ancestor of the current FO, else the initial value. + */ + public Property getNearestSpecified(String propertyName) { + Property p = null; + for (PropertyList plist = this; p == null && plist != null; + plist = plist.parentPropertyList) { + p = plist.getExplicit(propertyName); + } + if (p == null) { + // If no explicit setting found, return initial (default) value. + try { + p = this.builder.makeProperty(this, namespace, element, + propertyName); + } catch (FOPException e) { + //log.error("Exception in getNearestSpecified(): property=" + // + propertyName + " : " + e); + } + } + return p; + } + + /** + * Return the value of this property on the parent of this FO. + * Implements the from-parent function. + * @param propertyName The name of the property whose value is desired. + * @return The computed value on the parent or the initial value if this + * FO is the root or is in a different namespace from its parent. + */ + public Property getFromParent(String propertyName) { + if (parentPropertyList != null) { + return parentPropertyList.get(propertyName); + } else if (builder != null) { + // return the "initial" value + try { + return builder.makeProperty(this, namespace, element, + propertyName); + } catch (org.apache.fop.apps.FOPException e) { + //log.error("Exception in getFromParent(): property=" + // + propertyName + " : " + e); + } + } + return null; // No builder or exception in makeProperty! + } + + /** + * Given an absolute direction (top, bottom, left, right), + * return the corresponding writing model relative direction name + * for the flow object. Uses the stored writingMode. + */ + public String wmAbsToRel(int absdir) { + if (wmtable != null) { + return REL_NAMES[wmtable[absdir]]; + } else { + return ""; + } + } + + /** + * Given a writing mode relative direction (start, end, before, after) + * return the corresponding absolute direction name + * for the flow object. Uses the stored writingMode. + */ + public String wmRelToAbs(int reldir) { + if (wmtable != null) { + for (int i = 0; i < wmtable.length; i++) { + if (wmtable[i] == reldir) { + return ABS_NAMES[i]; + } + } + } + return ""; + } + + /** + * Set the writing mode traits for the FO with this property list. + */ + public void setWritingMode(int writingMode) { + this.wmtable = (byte[])WRITING_MODE_TABLES.get(new Integer(writingMode)); + } + +} + diff --git a/src/java/org/apache/fop/fo/PropertyListBuilder.java b/src/java/org/apache/fop/fo/PropertyListBuilder.java new file mode 100644 index 000000000..98fe85c01 --- /dev/null +++ b/src/java/org/apache/fop/fo/PropertyListBuilder.java @@ -0,0 +1,305 @@ +/* + * $Id: PropertyListBuilder.java,v 1.35 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.util.HashMap; +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; + +public class PropertyListBuilder { + + /** + * Name of font-size property attribute to set first. + */ + private static final String FONTSIZEATTR = "font-size"; + + private HashMap propertyListTable; + private HashMap elementTable; + + public PropertyListBuilder() { + this.propertyListTable = new HashMap(); + this.elementTable = new HashMap(); + } + + public void addList(HashMap list) { + propertyListTable.putAll(list); + } + + public void addElementList(String element, HashMap list) { + elementTable.put(element, list); + } + + public Property computeProperty(PropertyList propertyList, String space, + String element, String propertyName) { + + Property p = null; + Property.Maker propertyMaker = findMaker(space, element, + propertyName); + if (propertyMaker != null) { + try { + p = propertyMaker.compute(propertyList); + } catch (FOPException e) { + //log.error("exception occurred while computing" + // + " value of property '" + // + propertyName + "': " + // + e.getMessage()); + } + } else { + //log.error("property " + propertyName + // + " ignored"); + } + return p; + } + + public boolean isInherited(String space, String element, + String propertyName) { + boolean b; + + Property.Maker propertyMaker = findMaker(space, element, + propertyName); + if (propertyMaker != null) { + b = propertyMaker.isInherited(); + } else { + // log.error("Unknown property " + propertyName); + b = true; + } + return b; + } + + public PropertyList makeList(String ns, String elementName, Attributes attributes, + PropertyList parentPropertyList, + FObj parentFO) throws FOPException { + String space = "http://www.w3.org/TR/1999/XSL/Format"; + if (ns != null) { + space = ns; + } + + PropertyList par = null; + if (parentPropertyList != null + && space.equals(parentPropertyList.getNameSpace())) { + par = parentPropertyList; + } + PropertyList p = new PropertyList(par, space, + elementName); + p.setBuilder(this); + HashMap table; + table = (HashMap)elementTable.get(elementName); + + /* Store names of properties already set. */ + StringBuffer propsDone = new StringBuffer(256); + propsDone.append(' '); + + /* + * If font-size is set on this FO, must set it first, since + * other attributes specified in terms of "ems" depend on it. + * When we do "shorthand" properties, must handle the "font" + * property as well to see if font-size is set. + */ + String fontsizeval = attributes.getValue(FONTSIZEATTR); + if (fontsizeval != null) { + Property.Maker propertyMaker = findMaker(table, FONTSIZEATTR); + if (propertyMaker != null) { + try { + p.put(FONTSIZEATTR, + propertyMaker.make(p, fontsizeval, parentFO)); + } catch (FOPException e) { + /**@todo log this exception */ + } + } + // Put in the "done" list even if error or no Maker. + propsDone.append(FONTSIZEATTR + ' '); + } + + for (int i = 0; i < attributes.getLength(); i++) { + String attributeName = attributes.getQName(i); + /* Handle "compound" properties, ex. space-before.minimum */ + int sepchar = attributeName.indexOf('.'); + String propName = attributeName; + String subpropName = null; + Property propVal = null; + if (sepchar > -1) { + propName = attributeName.substring(0, sepchar); + subpropName = attributeName.substring(sepchar + 1); + } else if (propsDone.toString().indexOf(' ' + propName + ' ') + != -1) { + // Already processed this property (base property + // for a property with sub-components or font-size) + continue; + } + + Property.Maker propertyMaker = findMaker(table, propName); + + if (propertyMaker != null) { + try { + if (subpropName != null) { + Property baseProp = p.getExplicitBaseProp(propName); + if (baseProp == null) { + // See if it is specified later in this list + String baseValue = attributes.getValue(propName); + if (baseValue != null) { + baseProp = propertyMaker.make(p, baseValue, + parentFO); + propsDone.append(propName + ' '); + } + // else baseProp = propertyMaker.makeCompound(p, parentFO); + } + propVal = propertyMaker.make(baseProp, subpropName, + p, + attributes.getValue(i), + parentFO); + } else { + propVal = propertyMaker.make(p, + attributes.getValue(i), + parentFO); + } + if (propVal != null) { + p.put(propName, propVal); + } + } catch (FOPException e) { /* Do other props. */ + //log.error(e.getMessage()); + } + } else { + if (!attributeName.startsWith("xmlns")) { + //log.error("property '" + // + attributeName + "' ignored"); + } + } + } + + return p; + } + + public Property getSubpropValue(String space, String element, + String propertyName, Property p, + String subpropName) { + Property.Maker maker = findMaker(space, element, propertyName); + if (maker != null) { + return maker.getSubpropValue(p, subpropName); + } else { + return null; + } + } + + + public boolean isCorrespondingForced(PropertyList propertyList, + String space, String element, + String propertyName) { + Property.Maker propertyMaker = findMaker(space, element, + propertyName); + if (propertyMaker != null) { + return propertyMaker.isCorrespondingForced(propertyList); + } else { + //log.error("no Maker for " + propertyName); + } + return false; + } + + public Property getShorthand(PropertyList propertyList, String space, + String element, String propertyName) { + Property.Maker propertyMaker = findMaker(space, element, + propertyName); + if (propertyMaker != null) { + return propertyMaker.getShorthand(propertyList); + } else { + //log.error("no Maker for " + propertyName); + return null; + } + } + + + public Property makeProperty(PropertyList propertyList, String space, + String element, + String propertyName) throws FOPException { + + Property p = null; + + Property.Maker propertyMaker = findMaker(space, element, + propertyName); + if (propertyMaker != null) { + p = propertyMaker.make(propertyList); + } else { + //log.error("property " + propertyName + // + " ignored"); + } + return p; + } + + protected Property.Maker findMaker(String space, String elementName, + String propertyName) { + return findMaker((HashMap)elementTable.get(elementName), + propertyName); + } + + /** + * Convenience function to return the Maker for a given property + * given the HashMap containing properties specific to this element. + * If table is non-null and + * @param elemTable Element-specific properties or null if none. + * @param propertyName Name of property. + * @return A Maker for this property. + */ + private Property.Maker findMaker(HashMap elemTable, + String propertyName) { + Property.Maker propertyMaker = null; + if (elemTable != null) { + propertyMaker = (Property.Maker)elemTable.get(propertyName); + } + if (propertyMaker == null) { + propertyMaker = + (Property.Maker)propertyListTable.get(propertyName); + } + return propertyMaker; + } + +} diff --git a/src/java/org/apache/fop/fo/PropertyManager.java b/src/java/org/apache/fop/fo/PropertyManager.java new file mode 100644 index 000000000..221994cf7 --- /dev/null +++ b/src/java/org/apache/fop/fo/PropertyManager.java @@ -0,0 +1,582 @@ +/* + * $Id: PropertyManager.java,v 1.17 2003/03/05 20:38:27 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.text.MessageFormat; +import java.awt.geom.Rectangle2D; + +// FOP +import org.apache.fop.area.CTM; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layout.AbsolutePositionProps; +import org.apache.fop.traits.BlockProps; +import org.apache.fop.traits.InlineProps; +import org.apache.fop.traits.SpaceVal; +import org.apache.fop.traits.LayoutProps; // keep, break, span, space? +import org.apache.fop.fo.properties.Constants; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.fo.properties.Span; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.layout.HyphenationProps; + +/** + * Helper class for managing groups of properties. + */ +public class PropertyManager { + + private PropertyList properties; + private FontInfo fontInfo = null; + private FontState fontState = null; + private BorderAndPadding borderAndPadding = null; + private HyphenationProps hyphProps = null; + private TextInfo textInfo = null; + + private static final String[] SA_BEFORE = new String[]{"before"}; + private static final String[] SA_AFTER = new String[]{"after"}; + private static final String[] SA_START = new String[]{"start"}; + private static final String[] SA_END = new String[]{"end"}; + + private static final MessageFormat MSGFMT_COLOR = new MessageFormat("border-{0}-color"); + private static final MessageFormat MSGFMT_STYLE = new MessageFormat("border-{0}-style"); + private static final MessageFormat MSGFMT_WIDTH = new MessageFormat("border-{0}-width"); + private static final MessageFormat MSGFMT_PADDING = new MessageFormat("padding-{0}"); + + private static final String NONE = "none"; + + /** + * Main constructor + * @param pList property list + */ + public PropertyManager(PropertyList pList) { + this.properties = pList; + } + + /** + * Returns the property list that is used for lookup. + * @return the property list + */ + public PropertyList getProperties() { + return properties; + } + + /** + * Sets the FontInfo object telling the property manager which fonts are + * available. + * @param fontInfo available fonts + */ + public void setFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + + /** + * Constructs a FontState object. If it was constructed before it is + * reused. + * @param fontInfo FontInfo to work with + * @return a FontState object + */ + public FontState getFontState(FontInfo fontInfo) { + if (fontState == null) { + if (fontInfo == null) { + fontInfo = this.fontInfo; + } else if (this.fontInfo == null) { + this.fontInfo = fontInfo; + } + /**@todo this is ugly. need to improve. */ + + String fontFamily = properties.get("font-family").getString(); + String fontStyle = properties.get("font-style").getString(); + String fw = properties.get("font-weight").getString(); + int fontWeight = 400; + if (fw.equals("bolder")) { + // +100 from inherited + } else if (fw.equals("lighter")) { + // -100 from inherited + } else { + try { + fontWeight = Integer.parseInt(fw); + } catch (NumberFormatException nfe) { + } /**@todo log that exception */ + } + fontWeight = ((int) fontWeight / 100) * 100; + if (fontWeight < 100) { + fontWeight = 100; + } else if (fontWeight > 900) { + fontWeight = 900; + } + + // NOTE: this is incomplete. font-size may be specified with + // various kinds of keywords too + int fontSize = properties.get("font-size").getLength().getValue(); + //int fontVariant = properties.get("font-variant").getEnum(); + String fname = fontInfo.fontLookup(fontFamily, fontStyle, + fontWeight); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + fontState = new FontState(fname, metrics, fontSize); + } + return fontState; + } + + + /** + * Constructs a BorderAndPadding object. If it was constructed before it is + * reused. + * @return a BorderAndPadding object + */ + public BorderAndPadding getBorderAndPadding() { + if (borderAndPadding == null) { + this.borderAndPadding = new BorderAndPadding(); + + initBorderInfo(BorderAndPadding.BEFORE, SA_BEFORE); + initBorderInfo(BorderAndPadding.AFTER, SA_AFTER); + initBorderInfo(BorderAndPadding.START, SA_START); + initBorderInfo(BorderAndPadding.END, SA_END); + } + return borderAndPadding; + } + + private void initBorderInfo(int whichSide, String[] saSide) { + borderAndPadding.setPadding(whichSide, + properties.get( + MSGFMT_PADDING.format(saSide)).getCondLength()); + // If style = none, force width to 0, don't get Color + int style = properties.get(MSGFMT_STYLE.format(saSide)).getEnum(); + if (style != Constants.NONE) { + borderAndPadding.setBorder(whichSide, style, + properties.get( + MSGFMT_WIDTH.format(saSide)).getCondLength(), + properties.get( + MSGFMT_COLOR.format(saSide)).getColorType()); + } + } + + /** + * Constructs a HyphenationProps objects. If it was constructed before it is + * reused. + * @return a HyphenationProps object + */ + public HyphenationProps getHyphenationProps() { + if (hyphProps == null) { + this.hyphProps = new HyphenationProps(); + hyphProps.hyphenate = + this.properties.get("hyphenate").getEnum(); + hyphProps.hyphenationChar = this.properties.get( + "hyphenation-character").getCharacter(); + hyphProps.hyphenationPushCharacterCount = this.properties.get( + "hyphenation-push-character-count").getNumber(). + intValue(); + hyphProps.hyphenationRemainCharacterCount = this.properties.get( + "hyphenation-remain-character-count").getNumber(). + intValue(); + hyphProps.language = + this.properties.get("language").getString(); + hyphProps.country = this.properties.get("country").getString(); + } + return hyphProps; + } + + /*public int checkBreakBefore(Area area) { + if (!(area instanceof ColumnArea)) { + switch (properties.get("break-before").getEnum()) { + case BreakBefore.PAGE: + return Status.FORCE_PAGE_BREAK; + case BreakBefore.ODD_PAGE: + return Status.FORCE_PAGE_BREAK_ODD; + case BreakBefore.EVEN_PAGE: + return Status.FORCE_PAGE_BREAK_EVEN; + case BreakBefore.COLUMN: + return Status.FORCE_COLUMN_BREAK; + default: + return Status.OK; + } + } else { + ColumnArea colArea = (ColumnArea)area; + switch (properties.get("break-before").getEnum()) { + case BreakBefore.PAGE: + // if first ColumnArea, and empty, return OK + if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1)) + return Status.OK; + else + return Status.FORCE_PAGE_BREAK; + case BreakBefore.ODD_PAGE: + // if first ColumnArea, empty, _and_ in odd page, + // return OK + if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1) + && (colArea.getPage().getNumber() % 2 != 0)) + return Status.OK; + else + return Status.FORCE_PAGE_BREAK_ODD; + case BreakBefore.EVEN_PAGE: + // if first ColumnArea, empty, _and_ in even page, + // return OK + if (!colArea.hasChildren() && (colArea.getColumnIndex() == 1) + && (colArea.getPage().getNumber() % 2 == 0)) + return Status.OK; + else + return Status.FORCE_PAGE_BREAK_EVEN; + case BreakBefore.COLUMN: + // if ColumnArea is empty return OK + if (!area.hasChildren()) + return Status.OK; + else + return Status.FORCE_COLUMN_BREAK; + default: + return Status.OK; + } + } + } + + public int checkBreakAfter(Area area) { + switch (properties.get("break-after").getEnum()) { + case BreakAfter.PAGE: + return Status.FORCE_PAGE_BREAK; + case BreakAfter.ODD_PAGE: + return Status.FORCE_PAGE_BREAK_ODD; + case BreakAfter.EVEN_PAGE: + return Status.FORCE_PAGE_BREAK_EVEN; + case BreakAfter.COLUMN: + return Status.FORCE_COLUMN_BREAK; + default: + return Status.OK; + } + }*/ + + + /** + * Constructs a MarginProps objects. If it was constructed before it is + * reused. + * @return a MarginProps object + */ + public MarginProps getMarginProps() { + MarginProps props = new MarginProps(); + + // Common Margin Properties-Block + props.marginTop = + this.properties.get("margin-top").getLength().getValue(); + props.marginBottom = + this.properties.get("margin-bottom").getLength().getValue(); + props.marginLeft = + this.properties.get("margin-left").getLength().getValue(); + props.marginRight = + this.properties.get("margin-right").getLength().getValue(); + + // For now, we only get the optimum value for space-before and after + props.spaceBefore = this.properties.get("space-before"). + getSpace().getOptimum().getLength().getValue(); + props.spaceAfter = this.properties.get("space-after"). + getSpace().getOptimum().getLength().getValue(); + props.startIndent = this.properties.get("start-indent"). + getLength().getValue(); + props.endIndent = this.properties.get("end-indent"). + getLength().getValue(); + + return props; + } + + /** + * Constructs a BackgroundProps objects. If it was constructed before it is + * reused. + * @return a BackgroundProps object + */ + public BackgroundProps getBackgroundProps() { + BackgroundProps bp = new BackgroundProps(); + bp.backAttachment = properties.get("background-attachment").getEnum(); + bp.backColor = properties.get("background-color").getColorType(); + if (bp.backColor.alpha() == 1) { + bp.backColor = null; + } + + bp.backImage = properties.get("background-image").getString(); + if (bp.backImage == null || NONE.equals(bp.backImage)) { + bp.backImage = null; + } else { + bp.backRepeat = properties.get("background-repeat").getEnum(); + Property prop = properties.get("background-position-horizontal"); + if (prop != null) { + bp.backPosHorizontal = prop.getLength(); + } + prop = properties.get("background-position-vertical"); + if (prop != null) { + bp.backPosVertical = prop.getLength(); + } + } + + return bp; + } + + /** + * Constructs a MarginInlineProps objects. If it was constructed before it is + * reused. + * @return a MarginInlineProps object + */ + public MarginInlineProps getMarginInlineProps() { + MarginInlineProps props = new MarginInlineProps(); + return props; + } + + /** + * Constructs a InlineProps objects. If it was constructed before it is + * reused. + * @return a InlineProps object + */ + public InlineProps getInlineProps() { + InlineProps props = new InlineProps(); + props.spaceStart = new SpaceVal(properties.get("space-start").getSpace()); + props.spaceEnd = new SpaceVal(properties.get("space-end").getSpace()); + return props; + } + + /** + * Constructs a AccessibilityProps objects. If it was constructed before it is + * reused. + * @return a AccessibilityProps object + */ + public AccessibilityProps getAccessibilityProps() { + AccessibilityProps props = new AccessibilityProps(); + String str; + str = this.properties.get("source-document").getString(); + if (!NONE.equals(str)) { + props.sourceDoc = str; + } + str = this.properties.get("role").getString(); + if (!NONE.equals(str)) { + props.role = str; + } + return props; + } + + /** + * Constructs a AuralProps objects. If it was constructed before it is + * reused. + * @return a AuralProps object + */ + public AuralProps getAuralProps() { + AuralProps props = new AuralProps(); + return props; + } + + /** + * Constructs a RelativePositionProps objects. If it was constructed before it is + * reused. + * @return a RelativePositionProps object + */ + public RelativePositionProps getRelativePositionProps() { + RelativePositionProps props = new RelativePositionProps(); + return props; + } + + /** + * Constructs a AbsolutePositionProps objects. If it was constructed before + * it is reused. + * @return a AbsolutePositionProps object + */ + public AbsolutePositionProps getAbsolutePositionProps() { + AbsolutePositionProps props = new AbsolutePositionProps(); + props.absolutePosition = + this.properties.get("absolute-position").getEnum(); + props.top = this.properties.get("top").getLength().getValue(); + props.bottom = this.properties.get("bottom").getLength().getValue(); + props.left = this.properties.get("left").getLength().getValue(); + props.right = this.properties.get("right").getLength().getValue(); + return props; + } + + /** + * Constructs a BlockProps objects. If it was constructed before it is + * reused. + * @return a BlockProps object + */ + public BlockProps getBlockProps() { + BlockProps props = new BlockProps(); + props.firstIndent = this.properties.get("text-indent").getLength().getValue(); + props.lastIndent = 0; + /*this.properties.get("last-line-end-indent").getLength().mvalue(); */ + props.textAlign = this.properties.get("text-align").getEnum(); + props.textAlignLast = this.properties.get("text-align-last").getEnum(); + props.lineStackType = this.properties.get("line-stacking-strategy").getEnum(); + + return props; + } + + /** + * Constructs a LayoutProps objects. If it was constructed before it is + * reused. + * @return a LayoutProps object + */ + public LayoutProps getLayoutProps() { + LayoutProps props = new LayoutProps(); + props.breakBefore = this.properties.get("break-before").getEnum(); + props.breakAfter = this.properties.get("break-after").getEnum(); + props.bIsSpan = (this.properties.get("span").getEnum() == Span.ALL); + props.spaceBefore = new SpaceVal( + this.properties.get("space-before").getSpace()); + props.spaceAfter = new SpaceVal( + this.properties.get("space-after").getSpace()); + return props; + } + + /** + * Constructs a TextInfo objects. If it was constructed before it is + * reused. + * @param fontInfo available fonts + * @return a TextInfo object + */ + public TextInfo getTextLayoutProps(FontInfo fontInfo) { + if (textInfo == null) { + textInfo = new TextInfo(); + textInfo.fs = getFontState(fontInfo); + textInfo.color = properties.get("color").getColorType(); + + textInfo.verticalAlign = + properties.get("vertical-align").getEnum(); + + textInfo.wrapOption = properties.get("wrap-option").getEnum(); + textInfo.bWrap = (textInfo.wrapOption == Constants.WRAP); + + textInfo.wordSpacing = new SpaceVal( + properties.get("word-spacing").getSpace()); + + /* textInfo.letterSpacing = + new SpaceVal(properties.get("letter-spacing").getSpace());*/ + + textInfo.whiteSpaceCollapse = + properties.get("white-space-collapse").getEnum(); + + textInfo.lineHeight = this.properties.get( + "line-height").getLength().getValue(); + } + return textInfo; + } + + /** + * Construct a coordinate transformation matrix (CTM). + * @param absVPrect absolute viewpoint rectangle + * @param reldims relative dimensions + * @return CTM the coordinate transformation matrix (CTM) + */ + public CTM getCTMandRelDims(Rectangle2D absVPrect, + FODimension reldims) { + int width, height; + // We will use the absolute reference-orientation to set up the CTM. + // The value here is relative to its ancestor reference area. + int absRefOrient = getAbsRefOrient( + this.properties.get("reference-orientation").getNumber().intValue()); + if (absRefOrient % 180 == 0) { + width = (int) absVPrect.getWidth(); + height = (int) absVPrect.getHeight(); + } else { + // invert width and height since top left are rotated by 90 (cl or ccl) + height = (int) absVPrect.getWidth(); + width = (int) absVPrect.getHeight(); + } + /* Set up the CTM for the content of this reference area. + * This will transform region content coordinates in + * writing-mode relative into absolute page-relative + * which will then be translated based on the position of + * the region viewport. + * (Note: scrolling between region vp and ref area when + * doing online content!) + */ + CTM ctm = new CTM(absVPrect.getX(), absVPrect.getY()); + + // First transform for rotation + if (absRefOrient != 0) { + // Rotation implies translation to keep the drawing area in the + // first quadrant. Note: rotation is counter-clockwise + switch (absRefOrient) { + case 90: + ctm = ctm.translate(0, width); // width = absVPrect.height + break; + case 180: + ctm = ctm.translate(width, height); + break; + case 270: + ctm = ctm.translate(height, 0); // height = absVPrect.width + break; + } + ctm = ctm.rotate(absRefOrient); + } + int wm = this.properties.get("writing-mode").getEnum(); + /* Since we've already put adjusted width and height values for the + * top and left positions implied by the reference-orientation, we + * can set ipd and bpd appropriately based on the writing mode. + */ + + if (wm == WritingMode.LR_TB || wm == WritingMode.RL_TB) { + reldims.ipd = width; + reldims.bpd = height; + } else { + reldims.ipd = height; + reldims.bpd = width; + } + // Set a rectangle to be the writing-mode relative version??? + // Now transform for writing mode + return ctm.multiply(CTM.getWMctm(wm, reldims.ipd, reldims.bpd)); + } + + /** + * Calculate absolute reference-orientation relative to media orientation. + */ + private int getAbsRefOrient(int myRefOrient) { + return myRefOrient; + } +} + diff --git a/src/java/org/apache/fop/fo/RecursiveCharIterator.java b/src/java/org/apache/fop/fo/RecursiveCharIterator.java new file mode 100644 index 000000000..0f45dba76 --- /dev/null +++ b/src/java/org/apache/fop/fo/RecursiveCharIterator.java @@ -0,0 +1,134 @@ +/* + * $Id: RecursiveCharIterator.java,v 1.5 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import java.util.Iterator; +import java.util.NoSuchElementException; + + +public class RecursiveCharIterator extends AbstractCharIterator { + private Iterator childIter = null; // Child flow objects + private CharIterator curCharIter = null; // Children's characters + private FONode fobj; + private FONode curChild; + + public RecursiveCharIterator(FObj fobj) { + // Set up first child iterator + this.fobj = fobj; + this.childIter = fobj.getChildren(); + getNextCharIter(); + } + + public RecursiveCharIterator(FObj fobj, FONode child) { + // Set up first child iterator + this.fobj = fobj; + this.childIter = fobj.getChildren(child); + getNextCharIter(); + } + + public CharIterator mark() { + return (CharIterator) this.clone(); + } + + public Object clone() { + RecursiveCharIterator ci = (RecursiveCharIterator) super.clone(); + ci.childIter = fobj.getChildren(ci.curChild); + // Need to advance to the next child, else we get the same one!!! + ci.childIter.next(); + ci.curCharIter = (CharIterator) curCharIter.clone(); + return ci; + } + + + public void replaceChar(char c) { + if (curCharIter != null) { + curCharIter.replaceChar(c); + } + } + + + private void getNextCharIter() { + if (childIter != null && childIter.hasNext()) { + this.curChild = (FONode) childIter.next(); + this.curCharIter = curChild.charIterator(); + } else { + curChild = null; + curCharIter = null; + } + } + + public boolean hasNext() { + while (curCharIter != null) { + if (curCharIter.hasNext() == false) { + getNextCharIter(); + } else { + return true; + } + } + return false; + } + + public char nextChar() throws NoSuchElementException { + if (curCharIter != null) { + return curCharIter.nextChar(); + } else { + throw new NoSuchElementException(); + } + } + + + public void remove() { + if (curCharIter != null) { + curCharIter.remove(); + } + } +} + diff --git a/src/java/org/apache/fop/fo/ShorthandParser.java b/src/java/org/apache/fop/fo/ShorthandParser.java new file mode 100644 index 000000000..82c6a6d0c --- /dev/null +++ b/src/java/org/apache/fop/fo/ShorthandParser.java @@ -0,0 +1,57 @@ +/* + * $Id: ShorthandParser.java,v 1.3 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +public interface ShorthandParser { + Property getValueForProperty(String propName, + Property.Maker maker, + PropertyList propertyList); +} diff --git a/src/java/org/apache/fop/fo/SpaceProperty.java b/src/java/org/apache/fop/fo/SpaceProperty.java new file mode 100644 index 000000000..d0fac678e --- /dev/null +++ b/src/java/org/apache/fop/fo/SpaceProperty.java @@ -0,0 +1,84 @@ +/* + * $Id: SpaceProperty.java,v 1.5 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +import org.apache.fop.datatypes.Space; +import org.apache.fop.datatypes.LengthRange; + +public class SpaceProperty extends Property { + + public static class Maker extends LengthRangeProperty.Maker { + protected Maker(String name) { + super(name); + } + + } + + private Space space; + + public SpaceProperty(Space space) { + this.space = space; + } + + public Space getSpace() { + return this.space; + } + + /* Space extends LengthRange */ + public LengthRange getLengthRange() { + return this.space; + } + + public Object getObject() { + return this.space; + } + +} diff --git a/src/java/org/apache/fop/fo/StringProperty.java b/src/java/org/apache/fop/fo/StringProperty.java new file mode 100644 index 000000000..ef5fa9028 --- /dev/null +++ b/src/java/org/apache/fop/fo/StringProperty.java @@ -0,0 +1,107 @@ +/* + * $Id: StringProperty.java,v 1.4 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + + +public class StringProperty extends Property { + + public static class Maker extends Property.Maker { + + public Maker(String propName) { + super(propName); + } + + public Property make(PropertyList propertyList, String value, + FObj fo) { + // Work around the fact that most String properties are not + // specified as actual String literals (with "" or '') since + // the attribute values themselves are Strings! + // If the value starts with ' or ", make sure it also ends with + // this character + // Otherwise, just take the whole value as the String + int vlen = value.length() - 1; + if (vlen > 0) { + char q1 = value.charAt(0); + if (q1 == '"' || q1 == '\'') { + if (value.charAt(vlen) == q1) { + return new StringProperty(value.substring(1, vlen)); + } + System.err.println("Warning String-valued property starts with quote" + + " but doesn't end with quote: " + + value); + // fall through and use the entire value, including first quote + } + String str = checkValueKeywords(value); + if (str != null) { + value = str; + } + } + return new StringProperty(value); + } + + } // end String.Maker + + private String str; + + public StringProperty(String str) { + this.str = str; + // System.err.println("Set StringProperty: " + str); + } + + public Object getObject() { + return this.str; + } + + public String getString() { + return this.str; + } + +} diff --git a/src/java/org/apache/fop/fo/TextInfo.java b/src/java/org/apache/fop/fo/TextInfo.java new file mode 100644 index 000000000..cd1d307c2 --- /dev/null +++ b/src/java/org/apache/fop/fo/TextInfo.java @@ -0,0 +1,82 @@ +/* + * $Id: TextInfo.java,v 1.6 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// FOP +import org.apache.fop.layout.FontState; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.traits.SpaceVal; + +/** + * Collection of properties used in + */ +public class TextInfo { + public FontState fs; + public ColorType color; + public int wrapOption; + public boolean bWrap ; // True if wrap-option = WRAP + public int whiteSpaceCollapse; + public int verticalAlign; + public int lineHeight; + + // Props used for calculating inline-progression-dimension + public SpaceVal wordSpacing; + public SpaceVal letterSpacing; + + // Add hyphenation props too + public boolean bCanHyphenate = true; + + // Textdecoration + public boolean underlined = false; + public boolean overlined = false; + public boolean lineThrough = false; +} + diff --git a/src/java/org/apache/fop/fo/Title.java b/src/java/org/apache/fop/fo/Title.java new file mode 100644 index 000000000..1cbdf9585 --- /dev/null +++ b/src/java/org/apache/fop/fo/Title.java @@ -0,0 +1,131 @@ +/* + * $Id: Title.java,v 1.15 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// FOP +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.Length; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layoutmgr.ContentLayoutManager; +import org.apache.fop.layoutmgr.InlineStackingLayoutManager; +import org.apache.fop.layoutmgr.LMiter; + +/** + */ +public class Title extends FObjMixed { + + public Title(FONode parent) { + super(parent); + } + + public org.apache.fop.area.Title getTitleArea() { + org.apache.fop.area.Title title = + new org.apache.fop.area.Title(); + // use special layout manager to add the inline areas + // to the Title. + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setLMiter(new LMiter(children.listIterator())); + lm.init(); + + // get breaks then add areas to title + + ContentLayoutManager clm = new ContentLayoutManager(title); + clm.setUserAgent(getUserAgent()); + lm.setParent(clm); + + clm.fillArea(lm); + + return title; + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + FontState fontState = propMgr.getFontState(structHandler.getFontInfo()); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + Property prop; + prop = this.properties.get("baseline-shift"); + if (prop instanceof LengthProperty) { + Length bShift = prop.getLength(); + } else if (prop instanceof EnumProperty) { + int bShift = prop.getEnum(); + } + ColorType col = this.properties.get("color").getColorType(); + Length lHeight = this.properties.get("line-height").getLength(); + int lShiftAdj = this.properties.get( + "line-height-shift-adjustment").getEnum(); + int vis = this.properties.get("visibility").getEnum(); + Length zIndex = this.properties.get("z-index").getLength(); + + } +} + diff --git a/src/java/org/apache/fop/fo/ToBeImplementedElement.java b/src/java/org/apache/fop/fo/ToBeImplementedElement.java new file mode 100644 index 000000000..d8236a259 --- /dev/null +++ b/src/java/org/apache/fop/fo/ToBeImplementedElement.java @@ -0,0 +1,67 @@ +/* + * $Id: ToBeImplementedElement.java,v 1.8 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +/** + * This class is a placeholder for elements that have not been implemented. + */ +public class ToBeImplementedElement extends FObj { + + protected ToBeImplementedElement(FONode parent) { + super(parent); + } + + public void setup() { + getLogger().debug("This element \"" + this.name + + "\" is not yet implemented."); + } + +} diff --git a/src/java/org/apache/fop/fo/Unknown.java b/src/java/org/apache/fop/fo/Unknown.java new file mode 100644 index 000000000..2cff9bf37 --- /dev/null +++ b/src/java/org/apache/fop/fo/Unknown.java @@ -0,0 +1,74 @@ +/* + * $Id: Unknown.java,v 1.7 2003/03/05 21:48:01 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +/** + * This represents an unknown element. + * For example with unsupported namespaces. + * This prevents any further problems arising from the unknown + * data. + */ +public class Unknown extends FONode { + + public static class Maker extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new Unknown(parent); + } + } + + public Unknown(FONode parent) { + super(parent); + } + + public void setup() { + getLogger().debug("Layout Unknown element"); + } +} diff --git a/src/java/org/apache/fop/fo/UnknownXMLObj.java b/src/java/org/apache/fop/fo/UnknownXMLObj.java new file mode 100644 index 000000000..abb26e402 --- /dev/null +++ b/src/java/org/apache/fop/fo/UnknownXMLObj.java @@ -0,0 +1,98 @@ +/* + * $Id: UnknownXMLObj.java,v 1.7 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +public class UnknownXMLObj extends XMLObj { + private String namespace; + + public static class Maker extends ElementMapping.Maker { + private String space; + + public Maker(String sp) { + space = sp; + } + + public FONode make(FONode parent) { + return new UnknownXMLObj(parent, space); + } + } + + /** + * constructs an unknown xml object (called by Maker). + * + * @param parent the parent formatting object + * @param propertyList the explicit properties of this object + */ + protected UnknownXMLObj(FONode parent, String space) { + super(parent); + this.namespace = space; + } + + public String getNameSpace() { + return this.namespace; + } + + protected void addChild(FONode child) { + if (doc == null) { + createBasicDocument(); + } + super.addChild(child); + } + + protected void addCharacters(char data[], int start, int length) { + if (doc == null) { + createBasicDocument(); + } + super.addCharacters(data, start, length); + } + +} + diff --git a/src/java/org/apache/fop/fo/XMLElement.java b/src/java/org/apache/fop/fo/XMLElement.java new file mode 100644 index 000000000..3a2db0196 --- /dev/null +++ b/src/java/org/apache/fop/fo/XMLElement.java @@ -0,0 +1,88 @@ +/* + * $Id: XMLElement.java,v 1.5 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; + +/** + * class representing svg:svg pseudo flow object. + */ +public class XMLElement extends XMLObj { + + private String namespace = ""; + + /** + * constructs an XML object (called by Maker). + * + * @param parent the parent formatting object + * @param propertyList the explicit properties of this object + */ + public XMLElement(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + init(); + } + + private void init() { + createBasicDocument(); + } + + public String getNameSpace() { + return namespace; + } +} diff --git a/src/java/org/apache/fop/fo/XMLObj.java b/src/java/org/apache/fop/fo/XMLObj.java new file mode 100644 index 000000000..86edd893e --- /dev/null +++ b/src/java/org/apache/fop/fo/XMLObj.java @@ -0,0 +1,195 @@ +/* + * $Id: XMLObj.java,v 1.13 2003/03/05 21:48:02 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo; + +// Java +import java.awt.geom.Point2D; +import java.util.HashMap; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.Attributes; +import javax.xml.parsers.DocumentBuilderFactory; + +// FOP +import org.apache.fop.apps.FOPException; + +/** + * Generic XML object. + * This is used by xml objects (other than fo) than will build a DOM + * with each element. + */ +public abstract class XMLObj extends FONode { + + // temp reference for attributes + private Attributes attr = null; + + protected Element element; + protected Document doc; + + /** + * + * @param parent the parent formatting object + * @param propertyList the explicit properties of this object + */ + public XMLObj(FONode parent) { + super(parent); + } + + public void setName(String str) { + name = str; + } + + public void handleAttrs(Attributes attlist) throws FOPException { + attr = attlist; + } + + public Document getDocument() { + return doc; + } + + public Point2D getDimension(Point2D view) { + return null; + } + + public abstract String getNameSpace(); + + public String getDocumentNamespace() { + return getNameSpace(); + } + + protected static HashMap ns = new HashMap(); + static { + ns.put("xlink", "http://www.w3.org/1999/xlink"); + } + + public void addElement(Document doc, Element parent) { + this.doc = doc; + element = doc.createElementNS(getNameSpace(), name); + + for (int count = 0; count < attr.getLength(); count++) { + String rf = attr.getValue(count); + String qname = attr.getQName(count); + int idx = qname.indexOf(":"); + if (idx == -1) { + element.setAttribute(qname, rf); + } else { + String pref = qname.substring(0, idx); + String tail = qname.substring(idx + 1); + if (pref.equals("xmlns")) { + ns.put(tail, rf); + } else { + element.setAttributeNS((String)ns.get(pref), tail, rf); + } + } + } + attr = null; + parent.appendChild(element); + } + + public void buildTopLevel(Document doc, Element svgRoot) { + // build up the info for the top level element + for (int count = 0; count < attr.getLength(); count++) { + String rf = attr.getValue(count); + String qname = attr.getQName(count); + int idx = qname.indexOf(":"); + if (idx == -1) { + element.setAttribute(qname, rf); + } else { + String pref = qname.substring(0, idx); + String tail = qname.substring(idx + 1); + if (pref.equals("xmlns")) { + ns.put(tail, rf); + } else { + element.setAttributeNS((String)ns.get(pref), tail, rf); + } + } + } + } + + public Document createBasicDocument() { + doc = null; + + element = null; + try { + DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + doc = fact.newDocumentBuilder().newDocument(); + Element el = doc.createElement(name); + doc.appendChild(el); + + element = doc.getDocumentElement(); + buildTopLevel(doc, element); + } catch (Exception e) { + e.printStackTrace(); + } + return doc; + } + + protected void addChild(FONode child) { + if (child instanceof XMLObj) { + ((XMLObj)child).addElement(doc, element); + } else { + // in theory someone might want to embed some defined + // xml (eg. fo) inside the foreign xml + // they could use a different namespace + getLogger().debug("Invalid element: " + child.getName() + " inside foreign xml markup"); + } + } + + protected void addCharacters(char data[], int start, int length) { + String str = new String(data, start, length - start); + org.w3c.dom.Text text = doc.createTextNode(str); + element.appendChild(text); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/AbsFunction.java b/src/java/org/apache/fop/fo/expr/AbsFunction.java new file mode 100644 index 000000000..58f173f20 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/AbsFunction.java @@ -0,0 +1,72 @@ +/* + * $Id: AbsFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + +public class AbsFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo propInfo) throws PropertyException { + Numeric num = args[0].getNumeric(); + if (num == null) { + throw new PropertyException("Non numeric operand to abs function"); + } + // What if has relative composants (percent, table-col units)? + return new NumericProperty(num.abs()); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/BodyStartFunction.java b/src/java/org/apache/fop/fo/expr/BodyStartFunction.java new file mode 100644 index 000000000..7eb3ee773 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/BodyStartFunction.java @@ -0,0 +1,82 @@ +/* + * $Id: BodyStartFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.flow.ListItem; + +public class BodyStartFunction extends FunctionBase { + + public int nbArgs() { + return 0; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Numeric distance = + pInfo.getPropertyList().get("provisional-distance-between-starts").getNumeric(); + + FONode item = pInfo.getFO(); + while (item != null && !(item instanceof ListItem)) { + item = item.getParent(); + } + if (item == null) { + throw new PropertyException("body-start() called from outside an fo:list-item"); + } + + Numeric startIndent = + ((ListItem)item).properties.get("start-indent").getNumeric(); + + return new NumericProperty(distance.add(startIndent)); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/CeilingFunction.java b/src/java/org/apache/fop/fo/expr/CeilingFunction.java new file mode 100644 index 000000000..f43544e38 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/CeilingFunction.java @@ -0,0 +1,72 @@ +/* + * $Id: CeilingFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.NumberProperty; + +class CeilingFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Number dbl = args[0].getNumber(); + if (dbl == null) { + throw new PropertyException("Non number operand to ceiling function"); + } + return new NumberProperty(Math.ceil(dbl.doubleValue())); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/FloorFunction.java b/src/java/org/apache/fop/fo/expr/FloorFunction.java new file mode 100644 index 000000000..48913dd95 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/FloorFunction.java @@ -0,0 +1,73 @@ +/* + * $Id: FloorFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.NumberProperty; + + +class FloorFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Number dbl = args[0].getNumber(); + if (dbl == null) { + throw new PropertyException("Non number operand to floor function"); + } + return new NumberProperty(Math.floor(dbl.doubleValue())); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/FopPropValFunction.java b/src/java/org/apache/fop/fo/expr/FopPropValFunction.java new file mode 100644 index 000000000..16163f6c0 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/FopPropValFunction.java @@ -0,0 +1,75 @@ +/* + * $Id: FopPropValFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +/** + * Return the specified or initial value of the property on this object. + */ +public class FopPropValFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + String propName = args[0].getString(); + if (propName == null) { + throw new PropertyException("Incorrect parameter to _int-property-value function"); + } + // System.err.println("Get property-value for " + propName); + return pInfo.getPropertyList().get(propName); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/FromParentFunction.java b/src/java/org/apache/fop/fo/expr/FromParentFunction.java new file mode 100644 index 000000000..f22bb948f --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/FromParentFunction.java @@ -0,0 +1,79 @@ +/* + * $Id: FromParentFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +public class FromParentFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + String propName = args[0].getString(); + if (propName == null) { + throw new PropertyException("Incorrect parameter to from-parent function"); + } + // NOTE: special cases for shorthand property + // Should return COMPUTED VALUE + /* + * For now, this is the same as inherited-property-value(propName) + * (The only difference I can see is that this could work for + * non-inherited properties too. Perhaps the result is different for + * a property line line-height which "inherits specified"??? + */ + return pInfo.getPropertyList().getFromParent(propName); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java new file mode 100644 index 000000000..4f43aefee --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java @@ -0,0 +1,71 @@ +/* + * $Id: FromTableColumnFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +public class FromTableColumnFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + String propName = args[0].getString(); + if (propName == null) { + throw new PropertyException("Incorrect parameter to from-table-column function"); + } + throw new PropertyException("from-table-column unimplemented!"); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/Function.java b/src/java/org/apache/fop/fo/expr/Function.java new file mode 100644 index 000000000..b83463c92 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/Function.java @@ -0,0 +1,62 @@ +/* + * $Id: Function.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.datatypes.PercentBase; + +public interface Function { + int nbArgs(); + PercentBase getPercentBase(); + Property eval(Property[] args, + PropertyInfo propInfo) throws PropertyException; +} + diff --git a/src/java/org/apache/fop/fo/expr/FunctionBase.java b/src/java/org/apache/fop/fo/expr/FunctionBase.java new file mode 100644 index 000000000..d58e096b6 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/FunctionBase.java @@ -0,0 +1,70 @@ +/* + * $Id: FunctionBase.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.datatypes.PercentBase; + +public abstract class FunctionBase implements Function { + // abstract int nbArgs() ; + + /** + * By default, functions have no percent-based arguments. + */ + public PercentBase getPercentBase() { + return null; + } + + /* + * abstract Property eval(Property[] args, PropertyInfo propInfo) + * throws PropertyException; + */ +} + diff --git a/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java b/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java new file mode 100644 index 000000000..86937a489 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java @@ -0,0 +1,71 @@ +/* + * $Id: InheritedPropFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +public class InheritedPropFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + String propName = args[0].getString(); + if (propName == null) { + throw new PropertyException("Incorrect parameter to inherited-property-value function"); + } + return pInfo.getPropertyList().getInherited(propName); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/LabelEndFunction.java b/src/java/org/apache/fop/fo/expr/LabelEndFunction.java new file mode 100644 index 000000000..402a35306 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/LabelEndFunction.java @@ -0,0 +1,100 @@ +/* + * $Id: LabelEndFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.LengthBase; +import org.apache.fop.datatypes.LinearCombinationLength; +import org.apache.fop.datatypes.PercentLength; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.LengthProperty; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.flow.ListItem; + +public class LabelEndFunction extends FunctionBase { + + public int nbArgs() { + return 0; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + + Length distance = + pInfo.getPropertyList().get("provisional-distance-between-starts").getLength(); + Length separation = + pInfo.getPropertyList().getNearestSpecified("provisional-label-separation").getLength(); + + FONode item = pInfo.getFO(); + while (item != null && !(item instanceof ListItem)) { + item = item.getParent(); + } + if (item == null) { + throw new PropertyException("label-end() called from outside an fo:list-item"); + } + Length startIndent = ((ListItem)item).properties.get("start-indent").getLength(); + + LinearCombinationLength labelEnd = new LinearCombinationLength(); + + // Should be CONTAINING_REFAREA but that doesn't work + LengthBase base = new LengthBase((ListItem)item, pInfo.getPropertyList(), + LengthBase.CONTAINING_BOX); + PercentLength refWidth = new PercentLength(1.0, base); + + labelEnd.addTerm(1.0, refWidth); + labelEnd.addTerm(-1.0, distance); + labelEnd.addTerm(-1.0, startIndent); + labelEnd.addTerm(1.0, separation); + + return new LengthProperty(labelEnd); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/MaxFunction.java b/src/java/org/apache/fop/fo/expr/MaxFunction.java new file mode 100644 index 000000000..b45aef603 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/MaxFunction.java @@ -0,0 +1,73 @@ +/* + * $Id: MaxFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +public class MaxFunction extends FunctionBase { + public int nbArgs() { + return 2; + } + + // Handle "numerics" if no proportional/percent parts! + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Numeric n1 = args[0].getNumeric(); + Numeric n2 = args[1].getNumeric(); + if (n1 == null || n2 == null) { + throw new PropertyException("Non numeric operands to max function"); + } + return new NumericProperty(n1.max(n2)); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/MinFunction.java b/src/java/org/apache/fop/fo/expr/MinFunction.java new file mode 100644 index 000000000..c287772cf --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/MinFunction.java @@ -0,0 +1,73 @@ +/* + * $Id: MinFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + + +public class MinFunction extends FunctionBase { + public int nbArgs() { + return 2; + } + + // Handle "numerics" if no proportional/percent parts! + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Numeric n1 = args[0].getNumeric(); + Numeric n2 = args[1].getNumeric(); + if (n1 == null || n2 == null) { + throw new PropertyException("Non numeric operands to min function"); + } + return new NumericProperty(n1.min(n2)); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/NCnameProperty.java b/src/java/org/apache/fop/fo/expr/NCnameProperty.java new file mode 100644 index 000000000..3e3471693 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/NCnameProperty.java @@ -0,0 +1,80 @@ +/* + * $Id: NCnameProperty.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.datatypes.ColorType; + +public class NCnameProperty extends Property { + + private final String ncName; + + public NCnameProperty(String ncName) { + this.ncName = ncName; + } + + public ColorType getColor() throws PropertyException { + // If a system color, return the corresponding value + throw new PropertyException("Not a Color"); + } + + /** + * Return the name as a String (should be specified with quotes!) + */ + public String getString() { + return this.ncName; + } + + public String getNCname() { + return this.ncName; + } + +} diff --git a/src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java b/src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java new file mode 100644 index 000000000..c6036d5d4 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java @@ -0,0 +1,73 @@ +/* + * $Id: NearestSpecPropFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; + +public class NearestSpecPropFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + String propName = args[0].getString(); + if (propName == null) { + throw new PropertyException( + "Incorrect parameter to from-nearest-specified-value function"); + } + // NOTE: special cases for shorthand property + // Should return COMPUTED VALUE + return pInfo.getPropertyList().getNearestSpecified(propName); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/Numeric.java b/src/java/org/apache/fop/fo/expr/Numeric.java new file mode 100644 index 000000000..0315d0257 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/Numeric.java @@ -0,0 +1,420 @@ +/* + * $Id: Numeric.java,v 1.6 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import java.util.Vector; + +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.FixedLength; +import org.apache.fop.datatypes.PercentLength; +import org.apache.fop.datatypes.MixedLength; +import org.apache.fop.datatypes.TableColLength; +import org.apache.fop.datatypes.PercentBase; + +/** + * Represents a "numeric" value as defined by the XSL FO Specification. + * This consists of one or more kinds of value specifications, from + * absolute numbers (units power of 0) to lengths (unit power of 1), + * relative lengths (ems), percentage lengths. + * A Numeric can be constructed from other Property types representing + * Numbers or Length-type values. + * Numeric provides methods to return Number and Length values based on + * its current value. + * It supports basic arithmetic operations involving Numerics. + */ +public class Numeric { + // Bit fields + public static final int ABS_LENGTH = 1; // abs units (or number) + public static final int PC_LENGTH = 2; // Percentage + public static final int TCOL_LENGTH = 4; // Table units + + private int valType; + private double absValue; + private double pcValue; + private PercentBase pcBase = null; // base value for PC_LENGTH component + private double tcolValue; + private int dim; + + + /** + * Construct a Numeric object by specifying one or more components, + * including absolute length, percent length, table units. + * @param valType A combination of bits representing the value types. + * @param absValue The value of a Number or resolved Length value if + * the ABS_LENGTH flag is set. + * @param pcValue The decimal percent value if the PC_LENGTH flag is set + * @param tcolValue The decimal table unit value if the TCOL_LENGTH flag + * is set. + * @param dim The dimension of the value. 0 for a Number, 1 for a Length + * (any type), >1, <0 if Lengths have been multiplied or divided. + * @pcBase The PercentBase object used to calculate an actual value for + * a PC_LENGTH. + */ + protected Numeric(int valType, double absValue, double pcValue, + double tcolValue, int dim, PercentBase pcBase) { + this.valType = valType; + this.absValue = absValue; + this.pcValue = pcValue; + this.tcolValue = tcolValue; + this.dim = dim; + this.pcBase = pcBase; + } + + /** + * Construct a Numeric object of dimension 0 from a double. + * @param valType A combination of bits representing the value types. + * @param absValue The value of a Number or resolved Length value. + */ + + /** + * * + * protected Numeric(int valType, double absValue) { + * this.valType = valType; + * this.absValue = absValue; + * } + */ + + /** + * Construct a Numeric object from a Number. + * @param num The number. + */ + public Numeric(Number num) { + this(ABS_LENGTH, num.doubleValue(), 0.0, 0.0, 0, null); + } + + /** + * Construct a Numeric object from a Length. + * @param l The Length. + */ + public Numeric(FixedLength l) { + this(ABS_LENGTH, (double)l.getValue(), 0.0, 0.0, 1, null); + } + + /** + * Construct a Numeric object from a PercentLength. + * @param pclen The PercentLength. + */ + public Numeric(PercentLength pclen) { + this(PC_LENGTH, 0.0, pclen.value(), 0.0, 1, pclen.getBaseLength()); + } + + /** + * Construct a Numeric object from a TableColLength. + * @param tclen The TableColLength. + */ + public Numeric(TableColLength tclen) { + this(TCOL_LENGTH, 0.0, 0.0, tclen.getTableUnits(), 1, null); + } + + + /** + * Return the current value as a Length if possible. This constructs + * a new Length or Length subclass based on the current value type + * of the Numeric. + * If the stored value has a unit dimension other than 1, null + * is returned. + */ + public Length asLength() { + if (dim == 1) { + Vector len = new Vector(3); + if ((valType & ABS_LENGTH) != 0) { + len.add(new FixedLength((int)absValue)); + } + if ((valType & PC_LENGTH) != 0) { + len.add(new PercentLength(pcValue, pcBase)); + } + if ((valType & TCOL_LENGTH) != 0) { + len.add(new TableColLength(tcolValue)); + } + if (len.size() == 1) { + return (Length)len.elementAt(0); + } else { + return new MixedLength(len); + } + } else { + // or throw exception??? + // can't make Length if dimension != 1 + return null; + } + } + + /** + * Return the current value as a Number if possible. + * Calls asDouble(). + */ + public Number asNumber() { + return asDouble(); + } + + public Double asDouble() { + if (dim == 0 && valType == ABS_LENGTH) { + return new Double(absValue); + } else { + // or throw exception??? + // can't make Number if dimension != 0 + return null; + } + } + + /** + * Return the current value as a Integer if possible. + * If the unit dimension is 0 and the value type is ABSOLUTE, an Integer + * is returned. Otherwise null is returned. Note: the current value is + * truncated if necessary to make an integer value. + */ + + /** + * public Integer asInteger() { + * if (dim == 0 && valType==ABS_LENGTH) { + * return new Integer((int)absValue); + * } + * else { + * // or throw exception??? + * // can't make Number if dimension != 0 + * return null; + * } + * } + */ + + /** + * Return a boolean value indiciating whether the currently stored + * value consists of different "types" of values (absolute, percent, + * and/or table-unit.) + */ + private boolean isMixedType() { + int ntype = 0; + for (int t = valType; t != 0; t = t >> 1) { + if ((t & 1) != 0) { + ++ntype; + } + } + return ntype > 1; + } + + /** + * Subtract the operand from the current value and return a new Numeric + * representing the result. + * @param op The value to subtract. + * @return A Numeric representing the result. + * @throws PropertyException If the dimension of the operand is different + * from the dimension of this Numeric. + */ + public Numeric subtract(Numeric op) throws PropertyException { + // Check of same dimension + // Add together absolute and table units + // What about percentages??? Treat as colUnits if they can't be + // in same property! + if (dim == op.dim) { + PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase + : op.pcBase; + // Subtract each type of value + return new Numeric(valType | op.valType, absValue - op.absValue, + pcValue - op.pcValue, + tcolValue - op.tcolValue, dim, npcBase); + } else { + throw new PropertyException("Can't add Numerics of different dimensions"); + } + } + + /** + * Add the operand from the current value and return a new Numeric + * representing the result. + * @param op The value to add. + * @return A Numeric representing the result. + * @throws PropertyException If the dimension of the operand is different + * from the dimension of this Numeric. + */ + public Numeric add(Numeric op) throws PropertyException { + // Check of same dimension + // Add together absolute and table units + // What about percentages??? Treat as colUnits if they can't be + // in same property! + if (dim == op.dim) { + PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase + : op.pcBase; + // Add each type of value + return new Numeric(valType | op.valType, absValue + op.absValue, + pcValue + op.pcValue, + tcolValue + op.tcolValue, dim, npcBase); + } else { + throw new PropertyException("Can't add Numerics of different dimensions"); + } + } + + /** + * Multiply the the current value by the operand and return a new Numeric + * representing the result. + * @param op The multiplier. + * @return A Numeric representing the result. + * @throws PropertyException If both Numerics have "mixed" type. + */ + public Numeric multiply(Numeric op) throws PropertyException { + // Multiply together absolute units and add dimensions (exponents) + // What about percentages??? Treat as colUnits if they can't be + // in same property! + if (dim == 0) { + // This is a dimensionless quantity, ie. a "Number" + return new Numeric(op.valType, absValue * op.absValue, + absValue * op.pcValue, + absValue * op.tcolValue, op.dim, op.pcBase); + } else if (op.dim == 0) { + double opval = op.absValue; + return new Numeric(valType, opval * absValue, opval * pcValue, + opval * tcolValue, dim, pcBase); + } else if (valType == op.valType && !isMixedType()) { + // Check same relbase and pcbase ??? + PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase + : op.pcBase; + return new Numeric(valType, absValue * op.absValue, + pcValue * op.pcValue, + tcolValue * op.tcolValue, dim + op.dim, + npcBase); + } else { + throw new PropertyException("Can't multiply mixed Numerics"); + } + } + + /** + * Divide the the current value by the operand and return a new Numeric + * representing the result. + * @param op The divisor. + * @return A Numeric representing the result. + * @throws PropertyException If both Numerics have "mixed" type. + */ + public Numeric divide(Numeric op) throws PropertyException { + // Multiply together absolute units and add dimensions (exponents) + // What about percentages??? Treat as colUnits if they can't be + // in same property! + if (dim == 0) { + // This is a dimensionless quantity, ie. a "Number" + return new Numeric(op.valType, absValue / op.absValue, + absValue / op.pcValue, + absValue / op.tcolValue, -op.dim, op.pcBase); + } else if (op.dim == 0) { + double opval = op.absValue; + return new Numeric(valType, absValue / opval, pcValue / opval, + tcolValue / opval, dim, pcBase); + } else if (valType == op.valType && !isMixedType()) { + PercentBase npcBase = ((valType & PC_LENGTH) != 0) ? pcBase + : op.pcBase; + return new Numeric(valType, + (valType == ABS_LENGTH ? absValue / op.absValue : 0.0), + (valType == PC_LENGTH ? pcValue / op.pcValue : 0.0), + (valType == TCOL_LENGTH ? tcolValue / op.tcolValue : 0.0), + dim - op.dim, npcBase); + } else { + throw new PropertyException("Can't divide mixed Numerics."); + } + } + + /** + * Return the absolute value of this Numeric. + * @return A new Numeric object representing the absolute value. + */ + public Numeric abs() { + return new Numeric(valType, Math.abs(absValue), Math.abs(pcValue), + Math.abs(tcolValue), dim, pcBase); + } + + /** + * Return a Numeric which is the maximum of the current value and the + * operand. + * @throws PropertyException If the dimensions or value types of the + * object and the operand are different. + */ + public Numeric max(Numeric op) throws PropertyException { + double rslt = 0.0; + // Only compare if have same dimension and value type! + if (dim == op.dim && valType == op.valType && !isMixedType()) { + if (valType == ABS_LENGTH) { + rslt = absValue - op.absValue; + } else if (valType == PC_LENGTH) { + rslt = pcValue - op.pcValue; + } else if (valType == TCOL_LENGTH) { + rslt = tcolValue - op.tcolValue; + } + if (rslt > 0.0) { + return this; + } else { + return op; + } + } + throw new PropertyException("Arguments to max() must have same dimension and value type."); + } + + /** + * Return a Numeric which is the minimum of the current value and the + * operand. + * @throws PropertyException If the dimensions or value types of the + * object and the operand are different. + */ + public Numeric min(Numeric op) throws PropertyException { + double rslt = 0.0; + // Only compare if have same dimension and value type! + if (dim == op.dim && valType == op.valType && !isMixedType()) { + if (valType == ABS_LENGTH) { + rslt = absValue - op.absValue; + } else if (valType == PC_LENGTH) { + rslt = pcValue - op.pcValue; + } else if (valType == TCOL_LENGTH) { + rslt = tcolValue - op.tcolValue; + } + if (rslt > 0.0) { + return op; + } else { + return this; + } + } + throw new PropertyException("Arguments to min() must have same dimension and value type."); + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/NumericProperty.java b/src/java/org/apache/fop/fo/expr/NumericProperty.java new file mode 100644 index 000000000..9f28e14e8 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/NumericProperty.java @@ -0,0 +1,85 @@ +/* + * $Id: NumericProperty.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.fo.Property; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.ColorType; + +class NumericProperty extends Property { + private Numeric numeric; + + NumericProperty(Numeric value) { + this.numeric = value; + } + + public Numeric getNumeric() { + return this.numeric; + } + + public Number getNumber() { + return numeric.asNumber(); + } + + public Length getLength() { + return numeric.asLength(); + } + + public ColorType getColorType() { + // try converting to numeric number and then to color + return null; + } + + public Object getObject() { + return this.numeric; + } + +} diff --git a/src/java/org/apache/fop/fo/expr/PPColWidthFunction.java b/src/java/org/apache/fop/fo/expr/PPColWidthFunction.java new file mode 100644 index 000000000..c25b42a9f --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/PPColWidthFunction.java @@ -0,0 +1,78 @@ +/* + * $Id: PPColWidthFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.LengthProperty; +import org.apache.fop.datatypes.TableColLength; + +public class PPColWidthFunction extends FunctionBase { + + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Number d = args[0].getNumber(); + if (d == null) { + throw new PropertyException("Non number operand to proportional-column-width function"); + } + if (!pInfo.getPropertyList().getElement().equals("table-column")) { + throw new PropertyException("proportional-column-width function " + + "may only be used on table-column FO"); + } + // Check if table-layout is "fixed"... + return new LengthProperty(new TableColLength(d.doubleValue())); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/PropertyException.java b/src/java/org/apache/fop/fo/expr/PropertyException.java new file mode 100644 index 000000000..3c9d5a795 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/PropertyException.java @@ -0,0 +1,58 @@ +/* + * $Id: PropertyException.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +public class PropertyException extends Exception { + public PropertyException(String detail) { + super(detail); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/PropertyInfo.java b/src/java/org/apache/fop/fo/expr/PropertyInfo.java new file mode 100644 index 000000000..9731faf2d --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/PropertyInfo.java @@ -0,0 +1,138 @@ +/* + * $Id: PropertyInfo.java,v 1.4 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import java.util.Stack; + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.FObj; +import org.apache.fop.datatypes.PercentBase; + + +/** + * This class holds context information needed during property expression + * evaluation. + * It holds the Maker object for the property, the PropertyList being + * built, and the FObj parent of the FObj for which the property is being set. + */ +public class PropertyInfo { + private Property.Maker maker; + private PropertyList plist; + private FObj fo; + private Stack stkFunction; // Stack of functions being evaluated + + public PropertyInfo(Property.Maker maker, PropertyList plist, FObj fo) { + this.maker = maker; + this.plist = plist; + this.fo = fo; + } + + /** + * Return whether this property inherits specified values. + * Propagates to the Maker. + * @return true if the property inherits specified values, false if it + * inherits computed values. + */ + public boolean inheritsSpecified() { + return maker.inheritsSpecified(); + } + + /** + * Return the PercentBase object used to calculate the absolute value from + * a percent specification. + * Propagates to the Maker. + * @return The PercentBase object or null if percentLengthOK()=false. + */ + public PercentBase getPercentBase() { + PercentBase pcbase = getFunctionPercentBase(); + return (pcbase != null) ? pcbase : maker.getPercentBase(fo, plist); + } + + /** + * Return the current font-size value as base units (milli-points). + */ + public int currentFontSize() { + return plist.get("font-size").getLength().getValue(); + } + + public FObj getFO() { + return fo; + } + + public PropertyList getPropertyList() { + return plist; + } + + public void pushFunction(Function func) { + if (stkFunction == null) { + stkFunction = new Stack(); + } + stkFunction.push(func); + } + + public void popFunction() { + if (stkFunction != null) { + stkFunction.pop(); + } + } + + private PercentBase getFunctionPercentBase() { + if (stkFunction != null) { + Function f = (Function)stkFunction.peek(); + if (f != null) { + return f.getPercentBase(); + } + } + return null; + } + +} diff --git a/src/java/org/apache/fop/fo/expr/PropertyParser.java b/src/java/org/apache/fop/fo/expr/PropertyParser.java new file mode 100644 index 000000000..8fea26bc6 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/PropertyParser.java @@ -0,0 +1,499 @@ +/* + * $Id: PropertyParser.java,v 1.9 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.FixedLength; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.PercentBase; +import org.apache.fop.datatypes.PercentLength; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.ListProperty; +import org.apache.fop.fo.LengthProperty; +import org.apache.fop.fo.NumberProperty; +import org.apache.fop.fo.StringProperty; +import org.apache.fop.fo.ColorTypeProperty; + +import java.util.HashMap; + +/** + * Class to parse XSL FO property expression. + * This class is heavily based on the epxression parser in James Clark's + * XT, an XSLT processor. + */ +public class PropertyParser extends PropertyTokenizer { + private PropertyInfo propInfo; // Maker and propertyList related info + + private static final String RELUNIT = "em"; + private static final Numeric NEGATIVE_ONE = new Numeric(new Double(-1.0)); + private static final HashMap FUNCTION_TABLE = new HashMap(); + + static { + // Initialize the HashMap of XSL-defined functions + FUNCTION_TABLE.put("ceiling", new CeilingFunction()); + FUNCTION_TABLE.put("floor", new FloorFunction()); + FUNCTION_TABLE.put("round", new RoundFunction()); + FUNCTION_TABLE.put("min", new MinFunction()); + FUNCTION_TABLE.put("max", new MaxFunction()); + FUNCTION_TABLE.put("abs", new AbsFunction()); + FUNCTION_TABLE.put("rgb", new RGBColorFunction()); + FUNCTION_TABLE.put("from-table-column", new FromTableColumnFunction()); + FUNCTION_TABLE.put("inherited-property-value", + new InheritedPropFunction()); + FUNCTION_TABLE.put("from-parent", new FromParentFunction()); + FUNCTION_TABLE.put("from-nearest-specified-value", + new NearestSpecPropFunction()); + FUNCTION_TABLE.put("proportional-column-width", + new PPColWidthFunction()); + FUNCTION_TABLE.put("label-end", new LabelEndFunction()); + FUNCTION_TABLE.put("body-start", new BodyStartFunction()); + // NOTE: used from code generated for corresponding properties + FUNCTION_TABLE.put("_fop-property-value", new FopPropValFunction()); + + /** + * * NOT YET IMPLEMENTED!!! + * FUNCTION_TABLE.put("icc-color", new ICCcolorFunction()); + * FUNCTION_TABLE.put("system-color", new SystemColorFunction()); + * FUNCTION_TABLE.put("system-font", new SystemFontFunction()); + * + * FUNCTION_TABLE.put("merge-property-values", new MergePropsFunction()); + */ + } + + + /** + * Public entrypoint to the Property expression parser. + * @param expr The specified value (attribute on the xml element). + * @param propInfo A PropertyInfo object representing the context in + * which the property expression is to be evaluated. + * @return A Property object holding the parsed result. + * @throws PropertyException If the "expr" cannot be parsed as a Property. + */ + public static Property parse(String expr, PropertyInfo propInfo) + throws PropertyException { + return new PropertyParser(expr, propInfo).parseProperty(); + } + + + /** + * Private constructor. Called by the static parse() method. + * @param propExpr The specified value (attribute on the xml element). + * @param propInfo A PropertyInfo object representing the context in + * which the property expression is to be evaluated. + */ + private PropertyParser(String propExpr, PropertyInfo pInfo) { + super(propExpr); + this.propInfo = pInfo; + } + + /** + * Parse the property expression described in the instance variables. + * Note: If the property expression String is empty, a StringProperty + * object holding an empty String is returned. + * @return A Property object holding the parsed result. + * @throws PropertyException If the "expr" cannot be parsed as a Property. + */ + private Property parseProperty() throws PropertyException { + next(); + if (currentToken == TOK_EOF) { + // if prop value is empty string, force to StringProperty + return new StringProperty(""); + } + ListProperty propList = null; + while (true) { + Property prop = parseAdditiveExpr(); + if (currentToken == TOK_EOF) { + if (propList != null) { + propList.addProperty(prop); + return propList; + } else { + return prop; + } + } else { + if (propList == null) { + propList = new ListProperty(prop); + } else { + propList.addProperty(prop); + } + } + // throw new PropertyException("unexpected token"); + } + // return prop; + } + + /** + * Try to parse an addition or subtraction expression and return the + * resulting Property. + */ + private Property parseAdditiveExpr() throws PropertyException { + // Evaluate and put result on the operand stack + Property prop = parseMultiplicativeExpr(); + loop: + while (true) { + switch (currentToken) { + case TOK_PLUS: + next(); + prop = evalAddition(prop.getNumeric(), + parseMultiplicativeExpr().getNumeric()); + break; + case TOK_MINUS: + next(); + prop = + evalSubtraction(prop.getNumeric(), + parseMultiplicativeExpr().getNumeric()); + break; + default: + break loop; + } + } + return prop; + } + + /** + * Try to parse a multiply, divide or modulo expression and return + * the resulting Property. + */ + private Property parseMultiplicativeExpr() throws PropertyException { + Property prop = parseUnaryExpr(); + loop: + while (true) { + switch (currentToken) { + case TOK_DIV: + next(); + prop = evalDivide(prop.getNumeric(), + parseUnaryExpr().getNumeric()); + break; + case TOK_MOD: + next(); + prop = evalModulo(prop.getNumber(), + parseUnaryExpr().getNumber()); + break; + case TOK_MULTIPLY: + next(); + prop = evalMultiply(prop.getNumeric(), + parseUnaryExpr().getNumeric()); + break; + default: + break loop; + } + } + return prop; + } + + /** + * Try to parse a unary minus expression and return the + * resulting Property. + */ + private Property parseUnaryExpr() throws PropertyException { + if (currentToken == TOK_MINUS) { + next(); + return evalNegate(parseUnaryExpr().getNumeric()); + } + return parsePrimaryExpr(); + } + + + /** + * Checks that the current token is a right parenthesis + * and throws an exception if this isn't the case. + */ + private final void expectRpar() throws PropertyException { + if (currentToken != TOK_RPAR) { + throw new PropertyException("expected )"); + } + next(); + } + + /** + * Try to parse a primary expression and return the + * resulting Property. + * A primary expression is either a parenthesized expression or an + * expression representing a primitive Property datatype, such as a + * string literal, an NCname, a number or a unit expression, or a + * function call expression. + */ + private Property parsePrimaryExpr() throws PropertyException { + Property prop; + switch (currentToken) { + case TOK_LPAR: + next(); + prop = parseAdditiveExpr(); + expectRpar(); + return prop; + + case TOK_LITERAL: + prop = new StringProperty(currentTokenValue); + break; + + case TOK_NCNAME: + // Interpret this in context of the property or do it later? + prop = new NCnameProperty(currentTokenValue); + break; + + case TOK_FLOAT: + prop = new NumberProperty(new Double(currentTokenValue)); + break; + + case TOK_INTEGER: + prop = new NumberProperty(new Integer(currentTokenValue)); + break; + + case TOK_PERCENT: + /* + * Get the length base value object from the Maker. If null, then + * this property can't have % values. Treat it as a real number. + */ + double pcval = new Double(currentTokenValue.substring(0, + currentTokenValue.length() - 1)).doubleValue() / 100.0; + // LengthBase lbase = this.propInfo.getPercentLengthBase(); + PercentBase pcBase = this.propInfo.getPercentBase(); + if (pcBase != null) { + if (pcBase.getDimension() == 0) { + prop = new NumberProperty(pcval * pcBase.getBaseValue()); + } else if (pcBase.getDimension() == 1) { + prop = new LengthProperty(new PercentLength(pcval, + pcBase)); + } else { + throw new PropertyException("Illegal percent dimension value"); + } + } else { + // WARNING? Interpret as a decimal fraction, eg. 50% = .5 + prop = new NumberProperty(pcval); + } + break; + + case TOK_NUMERIC: + // A number plus a valid unit name. + int numLen = currentTokenValue.length() - currentUnitLength; + String unitPart = currentTokenValue.substring(numLen); + Double numPart = new Double(currentTokenValue.substring(0, + numLen)); + Length length = null; + if (unitPart.equals(RELUNIT)) { + length = new FixedLength(numPart.doubleValue(), + propInfo.currentFontSize()); + } else { + length = new FixedLength(numPart.doubleValue(), unitPart); + } + if (length == null) { + throw new PropertyException("unrecognized unit name: " + + currentTokenValue); + } else { + prop = new LengthProperty(length); + } + break; + + case TOK_COLORSPEC: + prop = new ColorTypeProperty(new ColorType(currentTokenValue)); + break; + + case TOK_FUNCTION_LPAR: { + Function function = + (Function)FUNCTION_TABLE.get(currentTokenValue); + if (function == null) { + throw new PropertyException("no such function: " + + currentTokenValue); + } + next(); + // Push new function (for function context: getPercentBase()) + propInfo.pushFunction(function); + prop = function.eval(parseArgs(function.nbArgs()), propInfo); + propInfo.popFunction(); + return prop; + } + default: + throw new PropertyException("syntax error"); + } + next(); + return prop; + } + + /** + * Parse a comma separated list of function arguments. Each argument + * may itself be an expression. This method consumes the closing right + * parenthesis of the argument list. + * @param nbArgs The number of arguments expected by the function. + * @return An array of Property objects representing the arguments + * found. + * @throws PropertyException If the number of arguments found isn't equal + * to the number expected. + */ + Property[] parseArgs(int nbArgs) throws PropertyException { + Property[] args = new Property[nbArgs]; + Property prop; + int i = 0; + if (currentToken == TOK_RPAR) { + // No args: func() + next(); + } else { + while (true) { + + prop = parseAdditiveExpr(); + if (i < nbArgs) { + args[i++] = prop; + } + // ignore extra args + if (currentToken != TOK_COMMA) { + break; + } + next(); + } + expectRpar(); + } + if (nbArgs != i) { + throw new PropertyException("Wrong number of args for function"); + } + return args; + } + + + /** + * Evaluate an addition operation. If either of the arguments is null, + * this means that it wasn't convertible to a Numeric value. + * @param op1 A Numeric object (Number or Length-type object) + * @param op2 A Numeric object (Number or Length-type object) + * @return A new NumericProperty object holding an object which represents + * the sum of the two operands. + * @throws PropertyException If either operand is null. + */ + private Property evalAddition(Numeric op1, + Numeric op2) throws PropertyException { + if (op1 == null || op2 == null) { + throw new PropertyException("Non numeric operand in addition"); + } + return new NumericProperty(op1.add(op2)); + } + + /** + * Evaluate a subtraction operation. If either of the arguments is null, + * this means that it wasn't convertible to a Numeric value. + * @param op1 A Numeric object (Number or Length-type object) + * @param op2 A Numeric object (Number or Length-type object) + * @return A new NumericProperty object holding an object which represents + * the difference of the two operands. + * @throws PropertyException If either operand is null. + */ + private Property evalSubtraction(Numeric op1, + Numeric op2) throws PropertyException { + if (op1 == null || op2 == null) { + throw new PropertyException("Non numeric operand in subtraction"); + } + return new NumericProperty(op1.subtract(op2)); + } + + /** + * Evaluate a unary minus operation. If the argument is null, + * this means that it wasn't convertible to a Numeric value. + * @param op A Numeric object (Number or Length-type object) + * @return A new NumericProperty object holding an object which represents + * the negative of the operand (multiplication by *1). + * @throws PropertyException If the operand is null. + */ + private Property evalNegate(Numeric op) throws PropertyException { + if (op == null) { + throw new PropertyException("Non numeric operand to unary minus"); + } + return new NumericProperty(op.multiply(NEGATIVE_ONE)); + } + + /** + * Evaluate a multiplication operation. If either of the arguments is null, + * this means that it wasn't convertible to a Numeric value. + * @param op1 A Numeric object (Number or Length-type object) + * @param op2 A Numeric object (Number or Length-type object) + * @return A new NumericProperty object holding an object which represents + * the product of the two operands. + * @throws PropertyException If either operand is null. + */ + private Property evalMultiply(Numeric op1, + Numeric op2) throws PropertyException { + if (op1 == null || op2 == null) { + throw new PropertyException("Non numeric operand in multiplication"); + } + return new NumericProperty(op1.multiply(op2)); + } + + + /** + * Evaluate a division operation. If either of the arguments is null, + * this means that it wasn't convertible to a Numeric value. + * @param op1 A Numeric object (Number or Length-type object) + * @param op2 A Numeric object (Number or Length-type object) + * @return A new NumericProperty object holding an object which represents + * op1 divided by op2. + * @throws PropertyException If either operand is null. + */ + private Property evalDivide(Numeric op1, + Numeric op2) throws PropertyException { + if (op1 == null || op2 == null) { + throw new PropertyException("Non numeric operand in division"); + } + return new NumericProperty(op1.divide(op2)); + } + + /** + * Evaluate a modulo operation. If either of the arguments is null, + * this means that it wasn't convertible to a Number value. + * @param op1 A Number object + * @param op2 A Number object + * @return A new NumberProperty object holding an object which represents + * op1 mod op2. + * @throws PropertyException If either operand is null. + */ + private Property evalModulo(Number op1, + Number op2) throws PropertyException { + if (op1 == null || op2 == null) { + throw new PropertyException("Non number operand to modulo"); + } + return new NumberProperty(op1.doubleValue() % op2.doubleValue()); + } + +} diff --git a/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java new file mode 100644 index 000000000..4a29973c3 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java @@ -0,0 +1,394 @@ +/* + * $Id: PropertyTokenizer.java,v 1.6 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + + + +/** + * Class to tokenize XSL FO property expression. + * This class is heavily based on the epxression tokenizer in James Clark's + * XT, an XSLT processor. + */ +class PropertyTokenizer { + + static final int TOK_EOF = 0; + static final int TOK_NCNAME = TOK_EOF + 1; + static final int TOK_MULTIPLY = TOK_NCNAME + 1; + static final int TOK_LPAR = TOK_MULTIPLY + 1; + static final int TOK_RPAR = TOK_LPAR + 1; + static final int TOK_LITERAL = TOK_RPAR + 1; + static final int TOK_NUMBER = TOK_LITERAL + 1; + static final int TOK_FUNCTION_LPAR = TOK_NUMBER + 1; + static final int TOK_PLUS = TOK_FUNCTION_LPAR + 1; + static final int TOK_MINUS = TOK_PLUS + 1; + static final int TOK_MOD = TOK_MINUS + 1; + static final int TOK_DIV = TOK_MOD + 1; + static final int TOK_NUMERIC = TOK_DIV + 1; + static final int TOK_COMMA = TOK_NUMERIC + 1; + static final int TOK_PERCENT = TOK_COMMA + 1; + static final int TOK_COLORSPEC = TOK_PERCENT + 1; + static final int TOK_FLOAT = TOK_COLORSPEC + 1; + static final int TOK_INTEGER = TOK_FLOAT + 1; + + protected int currentToken = TOK_EOF; + protected String currentTokenValue = null; + protected int currentUnitLength = 0; + + private int currentTokenStartIndex = 0; + private /* final */ String expr; + private int exprIndex = 0; + private int exprLength; + private boolean recognizeOperator = false; + + + /** + * Construct a new PropertyTokenizer object to tokenize the passed + * String. + * @param s The Property expressio to tokenize. + */ + PropertyTokenizer(String s) { + this.expr = s; + this.exprLength = s.length(); + } + + /** + * Return the next token in the expression string. + * This sets the following package visible variables: + * currentToken An enumerated value identifying the recognized token + * currentTokenValue A String containing the token contents + * currentUnitLength If currentToken = TOK_NUMERIC, the number of + * characters in the unit name. + * @throws PropertyException If un unrecognized token is encountered. + */ + void next() throws PropertyException { + currentTokenValue = null; + currentTokenStartIndex = exprIndex; + boolean currentMaybeOperator = recognizeOperator; + boolean bSawDecimal; + recognizeOperator = true; + for (; ;) { + if (exprIndex >= exprLength) { + currentToken = TOK_EOF; + return; + } + char c = expr.charAt(exprIndex++); + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + currentTokenStartIndex = exprIndex; + break; + case ',': + recognizeOperator = false; + currentToken = TOK_COMMA; + return; + case '+': + recognizeOperator = false; + currentToken = TOK_PLUS; + return; + case '-': + recognizeOperator = false; + currentToken = TOK_MINUS; + return; + case '(': + currentToken = TOK_LPAR; + recognizeOperator = false; + return; + case ')': + currentToken = TOK_RPAR; + return; + case '"': + case '\'': + exprIndex = expr.indexOf(c, exprIndex); + if (exprIndex < 0) { + exprIndex = currentTokenStartIndex + 1; + throw new PropertyException("missing quote"); + } + currentTokenValue = expr.substring(currentTokenStartIndex + + 1, exprIndex++); + currentToken = TOK_LITERAL; + return; + case '*': + /* + * if (currentMaybeOperator) { + * recognizeOperator = false; + */ + currentToken = TOK_MULTIPLY; + /* + * } + * else + * throw new PropertyException("illegal operator *"); + */ + return; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + scanDigits(); + if (exprIndex < exprLength && expr.charAt(exprIndex) == '.') { + exprIndex++; + bSawDecimal = true; + if (exprIndex < exprLength + && isDigit(expr.charAt(exprIndex))) { + exprIndex++; + scanDigits(); + } + } else { + bSawDecimal = false; + } + if (exprIndex < exprLength && expr.charAt(exprIndex) == '%') { + exprIndex++; + currentToken = TOK_PERCENT; + } else { + // Check for possible unit name following number + currentUnitLength = exprIndex; + scanName(); + currentUnitLength = exprIndex - currentUnitLength; + currentToken = (currentUnitLength > 0) ? TOK_NUMERIC + : (bSawDecimal ? TOK_FLOAT : TOK_INTEGER); + } + currentTokenValue = expr.substring(currentTokenStartIndex, + exprIndex); + return; + + case '.': + if (exprIndex < exprLength + && isDigit(expr.charAt(exprIndex))) { + ++exprIndex; + scanDigits(); + if (exprIndex < exprLength + && expr.charAt(exprIndex) == '%') { + exprIndex++; + currentToken = TOK_PERCENT; + } else { + // Check for possible unit name following number + currentUnitLength = exprIndex; + scanName(); + currentUnitLength = exprIndex - currentUnitLength; + currentToken = (currentUnitLength > 0) ? TOK_NUMERIC + : TOK_FLOAT; + } + currentTokenValue = expr.substring(currentTokenStartIndex, + exprIndex); + return; + } + throw new PropertyException("illegal character '.'"); + + case '#': // Start of color value + if (exprIndex < exprLength + && isHexDigit(expr.charAt(exprIndex))) { + ++exprIndex; + scanHexDigits(); + currentToken = TOK_COLORSPEC; + currentTokenValue = expr.substring(currentTokenStartIndex, + exprIndex); + // Probably should have some multiple of 3 for length! + return; + } else { + throw new PropertyException("illegal character '#'"); + } + + default: + --exprIndex; + scanName(); + if (exprIndex == currentTokenStartIndex) { + throw new PropertyException("illegal character"); + } + currentTokenValue = expr.substring(currentTokenStartIndex, + exprIndex); + // if (currentMaybeOperator) { + if (currentTokenValue.equals("mod")) { + currentToken = TOK_MOD; + return; + } else if (currentTokenValue.equals("div")) { + currentToken = TOK_DIV; + return; + } + /* + * else + * throw new PropertyException("unrecognized operator name"); + * recognizeOperator = false; + * return; + * } + */ + if (followingParen()) { + currentToken = TOK_FUNCTION_LPAR; + recognizeOperator = false; + } else { + currentToken = TOK_NCNAME; + recognizeOperator = false; + } + return; + } + } + } + + /** + * Attempt to recognize a valid NAME token in the input expression. + */ + private void scanName() { + if (exprIndex < exprLength && isNameStartChar(expr.charAt(exprIndex))) { + while (++exprIndex < exprLength + && isNameChar(expr.charAt(exprIndex))) { } + } + } + + /** + * Attempt to recognize a valid sequence of decimal DIGITS in the + * input expression. + */ + private void scanDigits() { + while (exprIndex < exprLength && isDigit(expr.charAt(exprIndex))) { + exprIndex++; + } + } + + /** + * Attempt to recognize a valid sequence of hexadecimal DIGITS in the + * input expression. + */ + private void scanHexDigits() { + while (exprIndex < exprLength && isHexDigit(expr.charAt(exprIndex))) { + exprIndex++; + } + } + + /** + * Return a boolean value indicating whether the following non-whitespace + * character is an opening parenthesis. + */ + private boolean followingParen() { + for (int i = exprIndex; i < exprLength; i++) { + switch (expr.charAt(i)) { + case '(': + exprIndex = i + 1; + return true; + case ' ': + case '\r': + case '\n': + case '\t': + break; + default: + return false; + } + } + return false; + } + + + private static final String NAME_START_CHARS = + "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static final String NAME_CHARS = ".-0123456789"; + private static final String DIGITS = "0123456789"; + private static final String HEX_CHARS = DIGITS + "abcdefABCDEF"; + + /** + * Return a boolean value indicating whether the argument is a + * decimal digit (0-9). + * @param c The character to check + */ + private static final boolean isDigit(char c) { + return DIGITS.indexOf(c) >= 0; + } + + /** + * Return a boolean value indicating whether the argument is a + * hexadecimal digit (0-9, A-F, a-f). + * @param c The character to check + */ + private static final boolean isHexDigit(char c) { + return HEX_CHARS.indexOf(c) >= 0; + } + + /** + * Return a boolean value indicating whether the argument is whitespace + * as defined by XSL (space, newline, CR, tab). + * @param c The character to check + */ + private static final boolean isSpace(char c) { + switch (c) { + case ' ': + case '\r': + case '\n': + case '\t': + return true; + } + return false; + } + + /** + * Return a boolean value indicating whether the argument is a valid name + * start character, ie. can start a NAME as defined by XSL. + * @param c The character to check + */ + private static final boolean isNameStartChar(char c) { + return NAME_START_CHARS.indexOf(c) >= 0 || c >= 0x80; + } + + /** + * Return a boolean value indicating whether the argument is a valid name + * character, ie. can occur in a NAME as defined by XSL. + * @param c The character to check + */ + private static final boolean isNameChar(char c) { + return NAME_START_CHARS.indexOf(c) >= 0 || NAME_CHARS.indexOf(c) >= 0 + || c >= 0x80; + } + +} + diff --git a/src/java/org/apache/fop/fo/expr/RGBColorFunction.java b/src/java/org/apache/fop/fo/expr/RGBColorFunction.java new file mode 100644 index 000000000..6b0b439aa --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/RGBColorFunction.java @@ -0,0 +1,110 @@ +/* + * $Id: RGBColorFunction.java,v 1.3 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.ColorTypeProperty; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.PercentBase; + +class RGBColorFunction extends FunctionBase { + public int nbArgs() { + return 3; + } + + /** + * Return an object which implements the PercentBase interface. + * Percents in arguments to this function are interpreted relative + * to 255. + */ + public PercentBase getPercentBase() { + return new RGBPercentBase(); + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + // Using CSS rules, numbers are either supposed to be 0-255 + // or percentage values. If percentages value, they've already + // been converted to reals. + float[] cfvals = new float[3]; // RGB + for (int i = 0; i < 3; i++) { + Number cval = args[i].getNumber(); + if (cval == null) { + throw new PropertyException("Argument to rgb() must be a Number"); + } + float colorVal = cval.floatValue() / 255f; + if (colorVal < 0.0 || colorVal > 255.0) { + throw new PropertyException( + "Arguments to rgb() must normalize to the range 0 to 1"); + } + cfvals[i] = colorVal; + } + return new ColorTypeProperty(new ColorType(cfvals[0], cfvals[1], + cfvals[2])); + + } + + static class RGBPercentBase implements PercentBase { + public int getDimension() { + return 0; + } + + public double getBaseValue() { + return 255f; + } + + public int getBaseLength() { + return 0; + } + + } +} diff --git a/src/java/org/apache/fop/fo/expr/RoundFunction.java b/src/java/org/apache/fop/fo/expr/RoundFunction.java new file mode 100644 index 000000000..1877c87f2 --- /dev/null +++ b/src/java/org/apache/fop/fo/expr/RoundFunction.java @@ -0,0 +1,77 @@ +/* + * $Id: RoundFunction.java,v 1.4 2003/03/05 21:59:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.expr; + + +import org.apache.fop.fo.Property; +import org.apache.fop.fo.NumberProperty; + +class RoundFunction extends FunctionBase { + public int nbArgs() { + return 1; + } + + public Property eval(Property[] args, + PropertyInfo pInfo) throws PropertyException { + Number dbl = args[0].getNumber(); + if (dbl == null) { + throw new PropertyException("Non number operand to round function"); + } + double n = dbl.doubleValue(); + double r = Math.floor(n + 0.5); + if (r == 0.0 && n < 0.0) { + r = -r; // round(-0.2) returns -0 not 0 + } + return new NumberProperty(r); + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/BasicLink.java b/src/java/org/apache/fop/fo/flow/BasicLink.java new file mode 100644 index 000000000..5076861cb --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/BasicLink.java @@ -0,0 +1,216 @@ +/* + * $Id: BasicLink.java,v 1.21 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; +import java.io.Serializable; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.Trait; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Area; +import org.apache.fop.layoutmgr.InlineStackingLayoutManager; +import org.apache.fop.layoutmgr.LMiter; +import org.apache.fop.layoutmgr.LayoutProcessor; + +/** + * The basic link. + * This sets the basic link trait on the inline parent areas + * that are created by the fo element. + */ +public class BasicLink extends Inline { + + private String link = null; + private boolean external = false; + + public BasicLink(FONode parent) { + super(parent); + } + + // add start and end properties for the link + public void addLayoutManager(List lms) { + setup(); + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager() { + protected InlineParent createArea() { + InlineParent area = super.createArea(); + setupLinkArea(parentLM, area); + return area; + } + }; + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setLMiter(new LMiter(children.listIterator())); + lms.add(lm); + } + + protected void setupLinkArea(LayoutProcessor parentLM, InlineParent area) { + if (link == null) { + return; + } + if (external) { + area.addTrait(Trait.EXTERNAL_LINK, link); + } else { + PageViewport page = parentLM.resolveRefID(link); + if (page != null) { + area.addTrait(Trait.INTERNAL_LINK, page.getKey()); + } else { + LinkResolver res = new LinkResolver(link, area); + parentLM.addUnresolvedArea(link, res); + } + } + } + + public void setup() { + String destination; + int linkType; + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("destination-place-offset"); + // this.properties.get("dominant-baseline"); + String ext = properties.get("external-destination").getString(); + setupID(); + // this.properties.get("indicate-destination"); + String internal = properties.get("internal-destination").getString(); + if (ext.length() > 0) { + link = ext; + external = true; + } else if (internal.length() > 0) { + link = internal; + } else { + getLogger().error("basic-link requires an internal or external destination"); + } + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("show-destination"); + // this.properties.get("target-processing-context"); + // this.properties.get("target-presentation-context"); + // this.properties.get("target-stylesheet"); + + } + + protected boolean containsMarkers() { + return true; + } + + /** + * Link resolving for resolving internal links. + * This is static since it is independant of the link fo. + */ + protected static class LinkResolver implements Resolveable, Serializable { + private boolean resolved = false; + private String idRef; + private Area area; + + /** + * Create a new link resolver. + * + * @param id the id to resolve + * @param a the area that will have the link attribute + */ + public LinkResolver(String id, Area a) { + idRef = id; + area = a; + } + + public boolean isResolved() { + return resolved; + } + + public String[] getIDs() { + return new String[] {idRef}; + } + + /** + * Resolve by adding an internal link. + */ + public void resolve(String id, List pages) { + resolved = true; + if (idRef.equals(id) && pages != null) { + PageViewport page = (PageViewport)pages.get(0); + area.addTrait(Trait.INTERNAL_LINK, page.getKey()); + } + } + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/BidiOverride.java b/src/java/org/apache/fop/fo/flow/BidiOverride.java new file mode 100644 index 000000000..8e53e1e0a --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/BidiOverride.java @@ -0,0 +1,154 @@ +/* + * $Id: BidiOverride.java,v 1.14 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.RelativePositionProps; + +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.area.inline.InlineArea; + +import java.util.List; +import java.util.ArrayList; + +/** + * fo:bidi-override element. + */ +public class BidiOverride extends FObjMixed { + + public BidiOverride(FONode parent) { + super(parent); + } + + public void addLayoutManager(List list) { + if (false) { + super.addLayoutManager(list); + } else { + ArrayList childList = new ArrayList(); + super.addLayoutManager(childList); + for (int count = childList.size() - 1; count >= 0; count--) { + LayoutProcessor lm = (LayoutProcessor) childList.get(count); + if (lm.generatesInlineAreas()) { + LayoutProcessor blm = new BidiLayoutManager((LeafNodeLayoutManager) lm); + blm.setFObj(this); + list.add(blm); + } else { + list.add(lm); + } + } + } + } + + public void setup() { + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Font Properties + //this.fontState = propMgr.getFontState(area.getFontInfo()); + + // Common Margin Properties-Inline + RelativePositionProps mProps = propMgr.getRelativePositionProps(); + + // this.properties.get("color"); + // this.properties.get("direction"); + setupID(); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("score-spaces"); + // this.properties.get("text-shadow"); + // this.properties.get("text-transform"); + // this.properties.get("unicode-bidi"); + // this.properties.get("word-spacing"); + + } + + protected boolean containsMarkers() { + return true; + } + + /** + * If this bidi has a different writing mode direction + * ltr or rtl than its parent writing mode then this + * reverses the inline areas (at the character level). + */ + class BidiLayoutManager extends LeafNodeLayoutManager { + + private List children; + + BidiLayoutManager(LeafNodeLayoutManager cLM) { + children = new ArrayList(); +/* for (int count = cLM.size() - 1; count >= 0; count--) { + InlineArea ia = cLM.get(count); + if (ia instanceof Word) { + // reverse word + Word word = (Word) ia; + StringBuffer sb = new StringBuffer(word.getWord()); + word.setWord(sb.reverse().toString()); + } + children.add(ia); + } +*/ } + + public int size() { + return children.size(); + } + + public InlineArea get(int index) { + return (InlineArea) children.get(index); + } + } +} diff --git a/src/java/org/apache/fop/fo/flow/Block.java b/src/java/org/apache/fop/fo/flow/Block.java new file mode 100644 index 000000000..35c1f1f19 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Block.java @@ -0,0 +1,385 @@ +/* + * $Id: Block.java,v 1.68 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.CharIterator; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FObjMixed; +import org.apache.fop.fo.RecursiveCharIterator; +import org.apache.fop.fo.TextInfo; +import org.apache.fop.fo.properties.Constants; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.HyphenationProps; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.BlockLayoutManager; +import org.apache.fop.util.CharUtilities; + +/* + Modified by Mark Lillywhite mark-fop@inomial.com. The changes + here are based on memory profiling and do not change functionality. + Essentially, the Block object had a pointer to a BlockArea object + that it created. The BlockArea was not referenced after the Block + was finished except to determine the size of the BlockArea, however + a reference to the BlockArea was maintained and this caused a lot of + GC problems, and was a major reason for FOP memory leaks. So, + the reference to BlockArea was made local, the required information + is now stored (instead of a reference to the complex BlockArea object) + and it appears that there are a lot of changes in this file, in fact + there are only a few sematic changes; mostly I just got rid of + "this." from blockArea since BlockArea is now local. + */ +public class Block extends FObjMixed { + + private int align; + private int alignLast; + private int breakAfter; + private int lineHeight; + private int startIndent; + private int endIndent; + private int spaceBefore; + private int spaceAfter; + private int textIndent; + private int keepWithNext; + private ColorType backgroundColor; + private int blockWidows; + private int blockOrphans; + + private String id; + private int span; + private int wsTreatment; //ENUMERATION + private int lfTreatment; //ENUMERATION + private boolean bWScollapse; //true if white-space-collapse=true + + // this may be helpful on other FOs too + private boolean anythingLaidOut = false; + + /** + * Index of first inline-type FO seen in a sequence. + * Used during FO tree building to do white-space handling. + */ + private FONode firstInlineChild = null; + + public Block(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + this.span = this.properties.get("span").getEnum(); + this.wsTreatment = + this.properties.get("white-space-treatment").getEnum(); + this.bWScollapse = + (this.properties.get("white-space-collapse").getEnum() + == Constants.TRUE); + this.lfTreatment = + this.properties.get("linefeed-treatment").getEnum(); + + setupID(); + + structHandler.startBlock(this); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + //this.fontState = propMgr.getFontState(area.getFontInfo()); + + // Common Hyphenation Properties + HyphenationProps mHyphProps = propMgr.getHyphenationProps(); + + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("break-after"); + // this.properties.get("break-before"); + // this.properties.get("color"); + // this.properties.get("text-depth"); + // this.properties.get("text-altitude"); + // this.properties.get("hyphenation-keep"); + // this.properties.get("hyphenation-ladder-count"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("last-line-end-indent"); + // this.properties.get("linefeed-treatment"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("line-stacking-strategy"); + // this.properties.get("orphans"); + // this.properties.get("white-space-treatment"); + // this.properties.get("span"); + // this.properties.get("text-align"); + // this.properties.get("text-align-last"); + // this.properties.get("text-indent"); + // this.properties.get("visibility"); + // this.properties.get("white-space-collapse"); + // this.properties.get("widows"); + // this.properties.get("wrap-option"); + // this.properties.get("z-index"); + + this.align = this.properties.get("text-align").getEnum(); + this.alignLast = + this.properties.get("text-align-last").getEnum(); + this.breakAfter = this.properties.get("break-after").getEnum(); + this.lineHeight = this.properties.get( + "line-height").getLength().getValue(); + this.startIndent = this.properties.get( + "start-indent").getLength().getValue(); + this.endIndent = this.properties.get( + "end-indent").getLength().getValue(); + this.spaceBefore = this.properties.get( + "space-before.optimum").getLength().getValue(); + this.spaceAfter = this.properties.get( + "space-after.optimum").getLength().getValue(); + this.textIndent = this.properties.get( + "text-indent").getLength().getValue(); + this.keepWithNext = + this.properties.get("keep-with-next").getEnum(); + + this.blockWidows = + this.properties.get("widows").getNumber().intValue(); + this.blockOrphans = + this.properties.get("orphans").getNumber().intValue(); + + } + + protected boolean containsMarkers() { + return true; + } + + public int getSpan() { + return this.span; + } + + public void addLayoutManager(List list) { + BlockLayoutManager blm = new BlockLayoutManager(); + blm.setUserAgent(getUserAgent()); + blm.setFObj(this); + TextInfo ti = propMgr.getTextLayoutProps(fontInfo); + blm.setBlockTextInfo(ti); + list.add(blm); + } + + public boolean generatesInlineAreas() { + return false; + } + + public void addChild(FONode child) { + // Handle whitespace based on values of properties + // Handle a sequence of inline-producing children in + // one pass + if (child instanceof FObj && ((FObj) child).generatesInlineAreas()) { + if (firstInlineChild == null) { + firstInlineChild = child; + } + // lastInlineChild = children.size(); + } else { + // Handle whitespace in preceeding inline areas if any + handleWhiteSpace(); + } + super.addChild(child); + } + + public void end() { + handleWhiteSpace(); + structHandler.endBlock(this); + } + + private void handleWhiteSpace() { + //getLogger().debug("fo:block: handleWhiteSpace"); + if (firstInlineChild != null) { + boolean bInWS = false; + boolean bPrevWasLF = false; + RecursiveCharIterator charIter = + new RecursiveCharIterator(this, firstInlineChild); + LFchecker lfCheck = new LFchecker(charIter); + + while (charIter.hasNext()) { + switch (CharUtilities.classOf(charIter.nextChar())) { + case CharUtilities.XMLWHITESPACE: + /* Some kind of whitespace character, except linefeed. */ + boolean bIgnore = false; + + switch (wsTreatment) { + case Constants.IGNORE: + bIgnore = true; + break; + case Constants.IGNORE_IF_BEFORE_LINEFEED: + bIgnore = lfCheck.nextIsLF(); + break; + case Constants.IGNORE_IF_SURROUNDING_LINEFEED: + bIgnore = (bPrevWasLF + || lfCheck.nextIsLF()); + break; + case Constants.IGNORE_IF_AFTER_LINEFEED: + bIgnore = bPrevWasLF; + break; + } + // Handle ignore + if (bIgnore) { + charIter.remove(); + } else if (bWScollapse) { + if (bInWS || (lfTreatment == Constants.PRESERVE + && (bPrevWasLF || lfCheck.nextIsLF()))) { + charIter.remove(); + } else { + bInWS = true; + } + } + break; + + case CharUtilities.LINEFEED: + /* A linefeed */ + lfCheck.reset(); + bPrevWasLF = true; // for following whitespace + + switch (lfTreatment) { + case Constants.IGNORE: + charIter.remove(); + break; + case Constants.TREAT_AS_SPACE: + if (bInWS) { + // only if bWScollapse=true + charIter.remove(); + } else { + if (bWScollapse) { + bInWS = true; + } + charIter.replaceChar('\u0020'); + } + break; + case Constants.TREAT_AS_ZERO_WIDTH_SPACE: + charIter.replaceChar('\u200b'); + // Fall through: this isn't XML whitespace + case Constants.PRESERVE: + bInWS = false; + break; + } + break; + + case CharUtilities.EOT: + // A "boundary" objects such as non-character inline + // or nested block object was encountered. + // If any whitespace run in progress, finish it. + // FALL THROUGH + + case CharUtilities.UCWHITESPACE: // Non XML-whitespace + case CharUtilities.NONWHITESPACE: + /* Any other character */ + bInWS = bPrevWasLF = false; + lfCheck.reset(); + break; + } + } + firstInlineChild = null; + } + } + + private static class LFchecker { + private boolean bNextIsLF = false; + private RecursiveCharIterator charIter; + + LFchecker(RecursiveCharIterator charIter) { + this.charIter = charIter; + } + + boolean nextIsLF() { + if (bNextIsLF == false) { + CharIterator lfIter = charIter.mark(); + while (lfIter.hasNext()) { + char c = lfIter.nextChar(); + if (c == '\n') { + bNextIsLF = true; + break; + } else if (CharUtilities.classOf(c) + != CharUtilities.XMLWHITESPACE) { + break; + } + } + } + return bNextIsLF; + } + + void reset() { + bNextIsLF = false; + } + } +} + diff --git a/src/java/org/apache/fop/fo/flow/BlockContainer.java b/src/java/org/apache/fop/fo/flow/BlockContainer.java new file mode 100644 index 000000000..0163c0094 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/BlockContainer.java @@ -0,0 +1,154 @@ +/* + * $Id: BlockContainer.java,v 1.22 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AbsolutePositionProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layoutmgr.BlockContainerLayoutManager; + +import org.xml.sax.Attributes; + +import java.util.List; + +public class BlockContainer extends FObj { + + private ColorType backgroundColor; + private int position; + + private int top; + private int bottom; + private int left; + private int right; + private int width; + private int height; + + private int span; + + public BlockContainer(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + this.span = this.properties.get("span").getEnum(); + setupID(); + } + + public void addLayoutManager(List list) { + BlockContainerLayoutManager blm = new BlockContainerLayoutManager(); + blm.setUserAgent(getUserAgent()); + blm.setFObj(this); + blm.setOverflow(properties.get("overflow").getEnum()); + list.add(blm); + } + + public void setup() { + + // Common Accessibility Properties + AbsolutePositionProps mAbsProps = propMgr.getAbsolutePositionProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin-Block Properties + MarginProps mProps = propMgr.getMarginProps(); + + // this.properties.get("block-progression-dimension"); + // this.properties.get("break-after"); + // this.properties.get("break-before"); + // this.properties.get("clip"); + // this.properties.get("display-align"); + // this.properties.get("height"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("overflow"); + // this.properties.get("reference-orientation"); + // this.properties.get("span"); + // this.properties.get("width"); + // this.properties.get("writing-mode"); + + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + this.width = this.properties.get("width").getLength().getValue(); + this.height = this.properties.get("height").getLength().getValue(); + span = this.properties.get("span").getEnum(); + + } + + public boolean generatesReferenceAreas() { + return true; + } + + public boolean generatesInlineAreas() { + return false; + } + + protected boolean containsMarkers() { + return true; + } + + public int getSpan() { + return this.span; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/Character.java b/src/java/org/apache/fop/fo/flow/Character.java new file mode 100644 index 000000000..d18924836 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Character.java @@ -0,0 +1,170 @@ +/* + * $Id: Character.java,v 1.22 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.fo.CharIterator; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.OneCharIterator; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.HyphenationProps; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; + +/** + * This class represents the flow object 'fo:character'. Its use is defined by + * the spec: "The fo:character flow object represents a character that is mapped to + * a glyph for presentation. It is an atomic unit to the formatter. + * When the result tree is interpreted as a tree of formatting objects, + * a character in the result tree is treated as if it were an empty + * element of type fo:character with a character attribute + * equal to the Unicode representation of the character. + * The semantics of an "auto" value for character properties, which is + * typically their initial value, are based on the Unicode codepoint. + * Overrides may be specified in an implementation-specific manner." (6.6.3) + * + */ +public class Character extends FObj { + + public static final int OK = 0; + public static final int DOESNOT_FIT = 1; + + private char characterValue; + + public Character(FONode parent) { + super(parent); + } + + public void addLayoutManager(List list) { + InlineArea inline = getInlineArea(); + if (inline != null) { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setCurrentArea(inline); + list.add(lm); + } + } + + protected InlineArea getInlineArea() { + String str = this.properties.get("character").getString(); + if (str.length() == 1) { + org.apache.fop.area.inline.Character ch = + new org.apache.fop.area.inline.Character( + str.charAt(0)); + return ch; + } + return null; + } + + public void setup() throws FOPException { + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + //this.fontState = propMgr.getFontState(area.getFontInfo()); + + // Common Hyphenation Properties + HyphenationProps mHyphProps = propMgr.getHyphenationProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("treat-as-word-space"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("character"); + // this.properties.get("color"); + // this.properties.get("dominant-baseline"); + // this.properties.get("text-depth"); + // this.properties.get("text-altitude"); + // this.properties.get("glyph-orientation-horizontal"); + // this.properties.get("glyph-orientation-vertical"); + setupID(); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("score-spaces"); + // this.properties.get("suppress-at-line-break"); + // this.properties.get("text-decoration"); + // this.properties.get("text-shadow"); + // this.properties.get("text-transform"); + // this.properties.get("word-spacing"); + } + + public CharIterator charIterator() { + return new OneCharIterator(characterValue); + // But what it the character is ignored due to white space handling? + } + + +} diff --git a/src/java/org/apache/fop/fo/flow/ExternalGraphic.java b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java new file mode 100644 index 000000000..97b3235c2 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java @@ -0,0 +1,321 @@ +/* + * $Id: ExternalGraphic.java,v 1.32 2003/03/05 20:38:21 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.fo.properties.TextAlign; +import org.apache.fop.fo.properties.Overflow; +import org.apache.fop.fo.properties.DisplayAlign; +import org.apache.fop.fo.properties.Scaling; +import org.apache.fop.image.ImageFactory; +import org.apache.fop.image.FopImage; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.inline.Image; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.datatypes.Length; + +// Java +import java.util.List; +import java.awt.geom.Rectangle2D; + +/** + * External graphic formatting object. + * This FO node handles the external graphic. It creates an image + * inline area that can be added to the area tree. + */ +public class ExternalGraphic extends FObj { + private String url; + private int breakAfter; + private int breakBefore; + private int align; + private int startIndent; + private int endIndent; + private int spaceBefore; + private int spaceAfter; + private int viewWidth = -1; + private int viewHeight = -1; + private boolean clip = false; + private Rectangle2D placement = null; + + /** + * Create a new External graphic node. + * + * @param parent the parent of this node + */ + public ExternalGraphic(FONode parent) { + super(parent); + } + + /** + * Add the layout manager for this to the list. + * This adds a leafnode layout manager that deals with the + * created viewport/image area. + * + * @param list the list to add the layout manager to + */ + public void addLayoutManager(List list) { + InlineArea area = getInlineArea(); + if (area != null) { + setupID(); + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setCurrentArea(area); + lm.setAlignment(properties.get("vertical-align").getEnum()); + lm.setLead(viewHeight); + list.add(lm); + } + } + + /** + * Get the inline area for this external grpahic. + * This creates the image area and puts it inside a viewport. + * + * @return the viewport containing the image area + */ + protected InlineArea getInlineArea() { + setup(); + if (url == null) { + return null; + } + Image imArea = new Image(url); + Viewport vp = new Viewport(imArea); + vp.setWidth(viewWidth); + vp.setHeight(viewHeight); + vp.setClip(clip); + vp.setContentPosition(placement); + vp.setOffset(0); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + TraitSetter.addBorders(vp, bap); + TraitSetter.addBackground(vp, bProps); + + return vp; + } + + /** + * Setup this image. + * This gets the sizes for the image and the dimensions and clipping. + */ + public void setup() { + url = this.properties.get("src").getString(); + if (url == null) { + return; + } + url = ImageFactory.getURL(url); + + // assume lr-tb for now + Length ipd = properties.get("inline-progression-dimension.optimum").getLength(); + if (!ipd.isAuto()) { + viewWidth = ipd.getValue(); + } else { + ipd = properties.get("width").getLength(); + if (!ipd.isAuto()) { + viewWidth = ipd.getValue(); + } + } + Length bpd = properties.get("block-progression-dimension.optimum").getLength(); + if (!bpd.isAuto()) { + viewHeight = bpd.getValue(); + } else { + bpd = properties.get("height").getLength(); + if (!bpd.isAuto()) { + viewHeight = bpd.getValue(); + } + } + + // if we need to load this image to get its size + FopImage fopimage = null; + + int cwidth = -1; + int cheight = -1; + Length ch = properties.get("content-height").getLength(); + if (!ch.isAuto()) { + /*if (ch.scaleToFit()) { + if (viewHeight != -1) { + cheight = viewHeight; + } + } else {*/ + cheight = ch.getValue(); + } + Length cw = properties.get("content-width").getLength(); + if (!cw.isAuto()) { + /*if (cw.scaleToFit()) { + if (viewWidth != -1) { + cwidth = viewWidth; + } + } else {*/ + cwidth = cw.getValue(); + } + + int scaling = properties.get("scaling").getEnum(); + if ((scaling == Scaling.UNIFORM) || (cwidth == -1) || cheight == -1) { + ImageFactory fact = ImageFactory.getInstance(); + fopimage = fact.getImage(url, userAgent); + if (fopimage == null) { + // error + url = null; + return; + } + // load dimensions + if (!fopimage.load(FopImage.DIMENSIONS, userAgent)) { + // error + url = null; + return; + } + if (cwidth == -1) { + cwidth = (int)(fopimage.getWidth() * 1000); + } + if (cheight == -1) { + cheight = (int)(fopimage.getHeight() * 1000); + } + if (scaling == Scaling.UNIFORM) { + // adjust the larger + double rat1 = cwidth / (fopimage.getWidth() * 1000f); + double rat2 = cheight / (fopimage.getHeight() * 1000f); + if (rat1 < rat2) { + // reduce cheight + cheight = (int)(rat1 * fopimage.getHeight() * 1000); + } else { + cwidth = (int)(rat2 * fopimage.getWidth() * 1000); + } + } + } + + if (viewWidth == -1) { + viewWidth = cwidth; + } + if (viewHeight == -1) { + viewHeight = cheight; + } + + if (cwidth > viewWidth || cheight > viewHeight) { + int overflow = properties.get("overflow").getEnum(); + if (overflow == Overflow.HIDDEN) { + clip = true; + } else if (overflow == Overflow.ERROR_IF_OVERFLOW) { + getLogger().error("Image: " + url + + " overflows the viewport, clipping to viewport"); + clip = true; + } + } + + int xoffset = 0; + int yoffset = 0; + int da = properties.get("display-align").getEnum(); + switch(da) { + case DisplayAlign.BEFORE: + break; + case DisplayAlign.AFTER: + yoffset = viewHeight - cheight; + break; + case DisplayAlign.CENTER: + yoffset = (viewHeight - cheight) / 2; + break; + case DisplayAlign.AUTO: + default: + break; + } + + int ta = properties.get("text-align").getEnum(); + switch(ta) { + case TextAlign.CENTER: + xoffset = (viewWidth - cwidth) / 2; + break; + case TextAlign.END: + xoffset = viewWidth - cwidth; + break; + case TextAlign.START: + break; + case TextAlign.JUSTIFY: + default: + break; + } + placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, cheight); + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("content-type"); + // this.properties.get("dominant-baseline"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("scaling-method"); + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/Float.java b/src/java/org/apache/fop/fo/flow/Float.java new file mode 100644 index 000000000..6782955e8 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Float.java @@ -0,0 +1,76 @@ +/* + * $Id: Float.java,v 1.8 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; + +/** + * fo:float element. + */ +public class Float extends ToBeImplementedElement { + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public Float(FONode parent) { + super(parent); + this.name = "fo:float"; + } + + public void setup() { + + // this.properties.get("float"); + // this.properties.get("clear"); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/Flow.java b/src/java/org/apache/fop/fo/flow/Flow.java new file mode 100644 index 000000000..c648d03e4 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Flow.java @@ -0,0 +1,163 @@ +/* + * $Id: Flow.java,v 1.37 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.ArrayList; +import java.util.List; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.FlowLayoutManager; + +public class Flow extends FObj { + + /** + * PageSequence container + */ + private PageSequence pageSequence; + + /** + * ArrayList to store snapshot + */ + private ArrayList markerSnapshot; + + /** + * flow-name attribute + */ + private String flowName; + + /** + * Content-width of current column area during layout + */ + private int contentWidth; + + + public Flow(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + if (parent.getName().equals("fo:page-sequence")) { + this.pageSequence = (PageSequence) parent; + } else { + throw new FOPException("flow must be child of " + + "page-sequence, not " + parent.getName()); + } + // according to communication from Paul Grosso (XSL-List, + // 001228, Number 406), confusion in spec section 6.4.5 about + // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1) + // fo:flow per fo:page-sequence only. + + /* if (pageSequence.isFlowSet()) { + if (this.name.equals("fo:flow")) { + throw new FOPException("Only a single fo:flow permitted" + + " per fo:page-sequence"); + } else { + throw new FOPException(this.name + + " not allowed after fo:flow"); + } + } + */ + setFlowName(getProperty("flow-name").getString()); + // Now done in addChild of page-sequence + //pageSequence.addFlow(this); + + structHandler.startFlow(this); + } + + public void end() { + structHandler.endFlow(this); + } + + protected void setFlowName(String name) throws FOPException { + if (name == null || name.equals("")) { + throw new FOPException("A 'flow-name' is required for " + + getName()); + } else { + flowName = name; + } + } + + public String getFlowName() { + return flowName; + } + + protected void setContentWidth(int contentWidth) { + this.contentWidth = contentWidth; + } + /** + * Return the content width of this flow (really of the region + * in which it is flowing). + */ + public int getContentWidth() { + return this.contentWidth; + } + + public boolean generatesReferenceAreas() { + return true; + } + + public void addLayoutManager(List list) { + FlowLayoutManager lm = new FlowLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + list.add(lm); + } + +} diff --git a/src/java/org/apache/fop/fo/flow/Footnote.java b/src/java/org/apache/fop/fo/flow/Footnote.java new file mode 100644 index 000000000..ffda294ee --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Footnote.java @@ -0,0 +1,89 @@ +/* + * $Id: Footnote.java,v 1.15 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; + +public class Footnote extends FObj { + + private Inline inlineFO = null; + private FootnoteBody body; + + public Footnote(FONode parent) { + super(parent); + } + + public void addLayoutManager(List lms) { + // add inlines layout manager + if (inlineFO == null) { + getLogger().error("inline required in footnote"); + return; + } + inlineFO.addLayoutManager(lms); + } + + public void addChild(FONode child) { + String name = child.getName(); + if ("fo:inline".equals(name)) { + inlineFO = (Inline)child; + } else if ("fo:footnote-body".equals(name)) { + body = (FootnoteBody)child; + } else { + getLogger().error("invalid child of footnote: " + name); + } + } +} + diff --git a/src/java/org/apache/fop/fo/flow/FootnoteBody.java b/src/java/org/apache/fop/fo/flow/FootnoteBody.java new file mode 100644 index 000000000..d29570bf1 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/FootnoteBody.java @@ -0,0 +1,70 @@ +/* + * $Id: FootnoteBody.java,v 1.12 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; + +public class FootnoteBody extends FObj { + + private int align; + private int alignLast; + private int lineHeight; + private int startIndent; + private int endIndent; + private int textIndent; + + public FootnoteBody(FONode parent) { + super(parent); + } + +} diff --git a/src/java/org/apache/fop/fo/flow/InitialPropertySet.java b/src/java/org/apache/fop/fo/flow/InitialPropertySet.java new file mode 100644 index 000000000..5e07fe4b6 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/InitialPropertySet.java @@ -0,0 +1,101 @@ +/* + * $Id: InitialPropertySet.java,v 1.9 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.RelativePositionProps; + +/** + * fo:initial-property-set element. + */ +public class InitialPropertySet extends ToBeImplementedElement { + + public InitialPropertySet(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + //this.fontState = propMgr.getFontState(area.getFontInfo()); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("color"); + setupID(); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("score-spaces"); + // this.properties.get("text-decoration"); + // this.properties.get("text-shadow"); + // this.properties.get("text-transform"); + // this.properties.get("word-spacing"); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/Inline.java b/src/java/org/apache/fop/fo/flow/Inline.java new file mode 100644 index 000000000..49fc1f611 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Inline.java @@ -0,0 +1,147 @@ +/* + * $Id: Inline.java,v 1.16 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.CharIterator; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; +import org.apache.fop.fo.InlineCharIterator; +import org.apache.fop.fo.properties.TextDecoration; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.apps.FOPException; + +public class Inline extends FObjMixed { + + // Textdecoration + protected boolean underlined = false; + protected boolean overlined = false; + protected boolean lineThrough = false; + + + public Inline(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + if (parent.getName().equals("fo:flow")) { + throw new FOPException("inline formatting objects cannot" + + " be directly under flow"); + } + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + //this.fontState = propMgr.getFontState(area.getFontInfo()); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("color"); + // this.properties.get("dominant-baseline"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("text-devoration"); + // this.properties.get("visibility"); + // this.properties.get("z-index"); + + int textDecoration = this.properties.get("text-decoration").getEnum(); + + if (textDecoration == TextDecoration.UNDERLINE) { + this.underlined = true; + } + + if (textDecoration == TextDecoration.OVERLINE) { + this.overlined = true; + } + + if (textDecoration == TextDecoration.LINE_THROUGH) { + this.lineThrough = true; + } + } + + protected boolean containsMarkers() { + return true; + } + + public CharIterator charIterator() { + return new InlineCharIterator(this, propMgr.getBorderAndPadding()); + } + +} diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java new file mode 100644 index 000000000..ab1dc1192 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java @@ -0,0 +1,145 @@ +/* + * $Id: InlineContainer.java,v 1.11 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; +import java.util.ArrayList; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.apps.FOPException; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.area.inline.InlineArea; + +/** + * fo:inline-container element. + */ +public class InlineContainer extends FObj { + + public InlineContainer(FONode parent) { + super(parent); + } + + public void addLayoutManager(List lms) { + ArrayList childList = new ArrayList(); + super.addLayoutManager(childList); + LayoutManager lm = new ICLayoutManager(childList); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lms.add(lm); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("block-progression-dimension"); + // this.properties.get("clip"); + // this.properties.get("display-align"); + // this.properties.get("dominant-baseline"); + // this.properties.get("height"); + setupID(); + // this.properties.get("inline-progression-dimension"); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("overflow"); + // this.properties.get("reference-orientation"); + // this.properties.get("width"); + // this.properties.get("writing-mode"); + } + + protected boolean containsMarkers() { + return true; + } + + /** + * 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. + */ + class ICLayoutManager extends LeafNodeLayoutManager { + + private List childrenLM; + + ICLayoutManager(List childLM) { + childrenLM = childLM; + } + + public InlineArea get(int index) { + return null; + } + } +} diff --git a/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java new file mode 100644 index 000000000..5f71404fd --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java @@ -0,0 +1,387 @@ +/* + * $Id: InstreamForeignObject.java,v 1.37 2003/03/05 20:38:21 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.util.List; + +import org.apache.fop.area.inline.ForeignObject; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.XMLObj; +import org.apache.fop.fo.properties.DisplayAlign; +import org.apache.fop.fo.properties.Overflow; +import org.apache.fop.fo.properties.Scaling; +import org.apache.fop.fo.properties.TextAlign; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.w3c.dom.Document; + +/** + * The instream-foreign-object flow formatting object. + * This is an atomic inline object that contains + * xml data. + */ +public class InstreamForeignObject extends FObj { + + private Viewport areaCurrent; + + /** + * constructs an instream-foreign-object object (called by Maker). + * + * @param parent the parent formatting object + */ + public InstreamForeignObject(FONode parent) { + super(parent); + } + + /** + * Add the layout manager for this into the list. + * @see org.apache.fop.fo.FObj#addLayoutManager(List) + */ + public void addLayoutManager(List list) { + areaCurrent = getInlineArea(); + if (areaCurrent != null) { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setCurrentArea(areaCurrent); + lm.setAlignment(properties.get("vertical-align").getEnum()); + lm.setLead(areaCurrent.getHeight()); + list.add(lm); + } + } + + /** + * Get the inline area created by this element. + * + * @return the viewport inline area + */ + protected Viewport getInlineArea() { + if (children == null) { + return areaCurrent; + } + + if (this.children.size() != 1) { + // error + return null; + } + FONode fo = (FONode)children.get(0); + if (!(fo instanceof XMLObj)) { + // error + return null; + } + XMLObj child = (XMLObj)fo; + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // viewport size is determined by block-progression-dimension + // and inline-progression-dimension + + // if replaced then use height then ignore block-progression-dimension + //int h = this.properties.get("height").getLength().mvalue(); + + // use specified line-height then ignore dimension in height direction + boolean hasLH = false;//properties.get("line-height").getSpecifiedValue() != null; + + Length len; + + int bpd = -1; + int ipd = -1; + boolean bpdauto = false; + if (hasLH) { + bpd = properties.get("line-height").getLength().getValue(); + } else { + // this property does not apply when the line-height applies + // isn't the block-progression-dimension always in the same + // direction as the line height? + len = properties.get("block-progression-dimension.optimum").getLength(); + if (!len.isAuto()) { + bpd = len.getValue(); + } else { + len = properties.get("height").getLength(); + if (!len.isAuto()) { + bpd = len.getValue(); + } + } + } + + len = properties.get("inline-progression-dimension.optimum").getLength(); + if (!len.isAuto()) { + ipd = len.getValue(); + } else { + len = properties.get("width").getLength(); + if (!len.isAuto()) { + ipd = len.getValue(); + } + } + + // if auto then use the intrinsic size of the content scaled + // to the content-height and content-width + int cwidth = -1; + int cheight = -1; + len = properties.get("content-width").getLength(); + if (!len.isAuto()) { + /*if(len.scaleToFit()) { + if(ipd != -1) { + cwidth = ipd; + } + } else {*/ + cwidth = len.getValue(); + } + len = properties.get("content-height").getLength(); + if (!len.isAuto()) { + /*if(len.scaleToFit()) { + if(bpd != -1) { + cwidth = bpd; + } + } else {*/ + cheight = len.getValue(); + } + + Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f, + cheight == -1 ? -1 : cheight / 1000f); + Point2D size = child.getDimension(csize); + if (size == null) { + // error + return null; + } + if (cwidth == -1) { + cwidth = (int)size.getX() * 1000; + } + if (cheight == -1) { + cheight = (int)size.getY() * 1000; + } + int scaling = properties.get("scaling").getEnum(); + if (scaling == Scaling.UNIFORM) { + // adjust the larger + double rat1 = cwidth / (size.getX() * 1000f); + double rat2 = cheight / (size.getY() * 1000f); + if (rat1 < rat2) { + // reduce cheight + cheight = (int)(rat1 * size.getY() * 1000); + } else { + cwidth = (int)(rat2 * size.getX() * 1000); + } + } + + if (ipd == -1) { + ipd = cwidth; + } + if (bpd == -1) { + bpd = cheight; + } + + boolean clip = false; + if (cwidth > ipd || cheight > bpd) { + int overflow = properties.get("overflow").getEnum(); + if (overflow == Overflow.HIDDEN) { + clip = true; + } else if (overflow == Overflow.ERROR_IF_OVERFLOW) { + getLogger().error("Instream foreign object overflows the viewport: clipping"); + clip = true; + } + } + + int xoffset = 0; + int yoffset = 0; + int da = properties.get("display-align").getEnum(); + switch (da) { + case DisplayAlign.BEFORE: + break; + case DisplayAlign.AFTER: + yoffset = bpd - cheight; + break; + case DisplayAlign.CENTER: + yoffset = (bpd - cheight) / 2; + break; + case DisplayAlign.AUTO: + default: + break; + } + + int ta = properties.get("text-align").getEnum(); + switch (ta) { + case TextAlign.CENTER: + xoffset = (ipd - cwidth) / 2; + break; + case TextAlign.END: + xoffset = ipd - cwidth; + break; + case TextAlign.START: + break; + case TextAlign.JUSTIFY: + default: + break; + } + Rectangle2D placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, cheight); + + Document doc = child.getDocument(); + String ns = child.getDocumentNamespace(); + + children = null; + ForeignObject foreign = new ForeignObject(doc, ns); + + areaCurrent = new Viewport(foreign); + areaCurrent.setWidth(ipd); + areaCurrent.setHeight(bpd); + areaCurrent.setContentPosition(placement); + areaCurrent.setClip(clip); + areaCurrent.setOffset(0); + + return areaCurrent; + } + + /** + * This flow object generates inline areas. + * @see org.apache.fop.fo.FObj#generatesInlineAreas() + * @return true + */ + public boolean generatesInlineAreas() { + return true; + } + + /* + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("block-progression-dimension"); + // this.properties.get("content-height"); + // this.properties.get("content-type"); + // this.properties.get("content-width"); + // this.properties.get("display-align"); + // this.properties.get("dominant-baseline"); + // this.properties.get("height"); + setupID(); + // this.properties.get("inline-progression-dimension"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("overflow"); + // this.properties.get("scaling"); + // this.properties.get("scaling-method"); + // this.properties.get("text-align"); + // this.properties.get("width"); + + /* retrieve properties * + int align = this.properties.get("text-align").getEnum(); + int valign = this.properties.get("vertical-align").getEnum(); + int overflow = this.properties.get("overflow").getEnum(); + + this.breakBefore = this.properties.get("break-before").getEnum(); + this.breakAfter = this.properties.get("break-after").getEnum(); + this.width = this.properties.get("width").getLength().mvalue(); + this.height = this.properties.get("height").getLength().mvalue(); + this.contwidth = + this.properties.get("content-width").getLength().mvalue(); + this.contheight = + this.properties.get("content-height").getLength().mvalue(); + this.wauto = this.properties.get("width").getLength().isAuto(); + this.hauto = this.properties.get("height").getLength().isAuto(); + this.cwauto = + this.properties.get("content-width").getLength().isAuto(); + this.chauto = + this.properties.get("content-height").getLength().isAuto(); + + this.startIndent = + this.properties.get("start-indent").getLength().mvalue(); + this.endIndent = + this.properties.get("end-indent").getLength().mvalue(); + this.spaceBefore = + this.properties.get("space-before.optimum").getLength().mvalue(); + this.spaceAfter = + this.properties.get("space-after.optimum").getLength().mvalue(); + + this.scaling = this.properties.get("scaling").getEnum(); + +*/ +} diff --git a/src/java/org/apache/fop/fo/flow/Leader.java b/src/java/org/apache/fop/fo/flow/Leader.java new file mode 100644 index 000000000..e4958f4bb --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Leader.java @@ -0,0 +1,308 @@ +/* + * $Id: Leader.java,v 1.35 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.FilledArea; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Word; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.PercentLength; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; +import org.apache.fop.fo.properties.LeaderPattern; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.ContentLayoutManager; +import org.apache.fop.layoutmgr.InlineStackingLayoutManager; +import org.apache.fop.layoutmgr.LMiter; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.util.CharUtilities; + +/** + * Implements fo:leader; main property of leader leader-pattern. + * The following patterns are treated: rule, space, dots and use-content. + */ +public class Leader extends FObjMixed { + + private int ruleStyle; + private int ruleThickness; + private int leaderPattern; + private int patternWidth; + protected FontInfo fontInfo = null; + protected FontState fontState; + protected InlineArea leaderArea = null; + + public Leader(FONode parent) { + super(parent); + } + + public void addLayoutManager(List list) { + LeafNodeLayoutManager lm = new LeafNodeLayoutManager() { + public InlineArea get(LayoutContext context) { + return getInlineArea(); + } + + protected MinOptMax getAllocationIPD(int refIPD) { + return getAllocIPD(refIPD); + } + + /*protected void offsetArea(LayoutContext context) { + if(leaderPattern == LeaderPattern.DOTS) { + curArea.setOffset(context.getBaseline()); + } + }*/ + }; + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setAlignment(properties.get("leader-alignment").getEnum()); + list.add(lm); + } + + protected InlineArea getInlineArea() { + if (leaderArea == null) { + createLeaderArea(); + } + return leaderArea; + } + + protected void createLeaderArea() { + setup(); + + if (leaderPattern == LeaderPattern.RULE) { + org.apache.fop.area.inline.Leader leader = new org.apache.fop.area.inline.Leader(); + + leader.setRuleStyle(ruleStyle); + leader.setRuleThickness(ruleThickness); + + leaderArea = leader; + } else if (leaderPattern == LeaderPattern.SPACE) { + leaderArea = new Space(); + } else if (leaderPattern == LeaderPattern.DOTS) { + Word w = new Word(); + char dot = '.'; // userAgent.getLeaderDotCharacter(); + + w.setWord("" + dot); + w.addTrait(Trait.FONT_NAME, fontState.getFontName()); + w.addTrait(Trait.FONT_SIZE, + new Integer(fontState.getFontSize())); + // set offset of dot within inline parent + w.setOffset(fontState.getAscender()); + int width = CharUtilities.getCharWidth(dot, fontState); + Space spacer = null; + if (patternWidth > width) { + spacer = new Space(); + spacer.setWidth(patternWidth - width); + width = patternWidth; + } + FilledArea fa = new FilledArea(); + fa.setUnitWidth(width); + fa.addChild(w); + if (spacer != null) { + fa.addChild(spacer); + } + fa.setHeight(fontState.getAscender()); + + leaderArea = fa; + } else if (leaderPattern == LeaderPattern.USECONTENT) { + if (children == null) { + getLogger().error("Leader use-content with no content"); + return; + } + InlineStackingLayoutManager lm; + lm = new InlineStackingLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lm.setLMiter(new LMiter(children.listIterator())); + lm.init(); + + // get breaks then add areas to FilledArea + FilledArea fa = new FilledArea(); + + ContentLayoutManager clm = new ContentLayoutManager(fa); + clm.setUserAgent(getUserAgent()); + lm.setParent(clm); + + clm.fillArea(lm); + int width = clm.getStackingSize(); + Space spacer = null; + if (patternWidth > width) { + spacer = new Space(); + spacer.setWidth(patternWidth - width); + width = patternWidth; + } + fa.setUnitWidth(width); + if (spacer != null) { + fa.addChild(spacer); + } + leaderArea = fa; + } + } + + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + fontInfo = st.getFontInfo(); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + this.fontState = propMgr.getFontState(fontInfo); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("color"); + // this.properties.get("dominant-baseline"); + // this.properties.get("text-depth"); + // this.properties.get("text-altitude"); + setupID(); + // this.properties.get("leader-alignment"); + // this.properties.get("leader-length"); + // this.properties.get("leader-pattern"); + // this.properties.get("leader-pattern-width"); + // this.properties.get("rule-style"); + // this.properties.get("rule-thickness"); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("text-shadow"); + // this.properties.get("visibility"); + // this.properties.get("word-spacing"); + // this.properties.get("z-index"); + + // color properties + ColorType c = this.properties.get("color").getColorType(); + float red = c.getRed(); + float green = c.getGreen(); + float blue = c.getBlue(); + + // fo:leader specific properties + // determines the pattern of leader; allowed values: space, rule,dots, use-content + leaderPattern = this.properties.get("leader-pattern").getEnum(); + switch(leaderPattern) { + case LeaderPattern.SPACE: + // use Space + break; + case LeaderPattern.RULE: + // the following properties only apply + // for leader-pattern = "rule" + ruleThickness = + properties.get("rule-thickness").getLength().getValue(); + ruleStyle = properties.get("rule-style").getEnum(); + break; + case LeaderPattern.DOTS: + break; + case LeaderPattern.USECONTENT: + // use inline layout manager to create inline areas + // add the inline parent multiple times until leader full + break; + } + + // if leaderPatternWidth = 0 = default = use-font-metric + patternWidth = + this.properties.get("leader-pattern-width").getLength().getValue(); + + } + + protected MinOptMax getAllocIPD(int ipd) { + // length of the leader + int opt = getLength("leader-length.optimum", ipd); + int min = getLength("leader-length.minimum", ipd); + int max = getLength("leader-length.maximum", ipd); + + return new MinOptMax(min, opt, max); + } + + protected int getLength(String prop, int dim) { + int length; + Length maxlength = properties.get(prop).getLength(); + if (maxlength instanceof PercentLength) { + length = (int)(((PercentLength)maxlength).value() + * dim); + } else { + length = maxlength.getValue(); + } + return length; + } +} + diff --git a/src/java/org/apache/fop/fo/flow/ListBlock.java b/src/java/org/apache/fop/fo/flow/ListBlock.java new file mode 100644 index 000000000..6618ead78 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/ListBlock.java @@ -0,0 +1,148 @@ +/* + * $Id: ListBlock.java,v 1.33 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.list.ListBlockLayoutManager; + +public class ListBlock extends FObj { + + private int align; + private int alignLast; + private int breakBefore; + private int breakAfter; + private int lineHeight; + private int startIndent; + private int endIndent; + private int spaceBefore; + private int spaceAfter; + private int spaceBetweenListRows = 0; + private ColorType backgroundColor; + + public ListBlock(FONode parent) { + super(parent); + } + + public void addLayoutManager(List list) { + ListBlockLayoutManager blm = new ListBlockLayoutManager(); + blm.setUserAgent(getUserAgent()); + blm.setFObj(this); + list.add(blm); + } + + public void setup() throws FOPException { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("break-after"); + // this.properties.get("break-before"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("provisional-distance-between-starts"); + // this.properties.get("provisional-label-separation"); + + this.align = this.properties.get("text-align").getEnum(); + this.alignLast = this.properties.get("text-align-last").getEnum(); + this.lineHeight = + this.properties.get("line-height").getLength().getValue(); + this.startIndent = + this.properties.get("start-indent").getLength().getValue(); + this.endIndent = + this.properties.get("end-indent").getLength().getValue(); + this.spaceBefore = + this.properties.get("space-before.optimum").getLength().getValue(); + this.spaceAfter = + this.properties.get("space-after.optimum").getLength().getValue(); + this.spaceBetweenListRows = 0; // not used at present + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + } + + public boolean generatesInlineAreas() { + return false; + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/ListItem.java b/src/java/org/apache/fop/fo/flow/ListItem.java new file mode 100644 index 000000000..a3e9a3b17 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/ListItem.java @@ -0,0 +1,157 @@ +/* + * $Id: ListItem.java,v 1.30 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.list.ListItemLayoutManager; + +public class ListItem extends FObj { + + private ListItemLabel label = null; + private ListItemBody body = null; + + private int align; + private int alignLast; + private int breakBefore; + private int breakAfter; + private int lineHeight; + private int startIndent; + private int endIndent; + private int spaceBefore; + private int spaceAfter; + + public ListItem(FONode parent) { + super(parent); + } + + public void addLayoutManager(List list) { + if (label != null && body != null) { + ListItemLayoutManager blm = new ListItemLayoutManager(); + blm.setUserAgent(getUserAgent()); + blm.setFObj(this); + blm.setLabel(label.getItemLayoutManager()); + blm.setBody(body.getItemLayoutManager()); + list.add(blm); + } else { + getLogger().error("list-item requires list-item-label and list-item-body"); + } + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("break-after"); + // this.properties.get("break-before"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("relative-align"); + + this.align = this.properties.get("text-align").getEnum(); + this.alignLast = this.properties.get("text-align-last").getEnum(); + this.lineHeight = + this.properties.get("line-height").getLength().getValue(); + this.spaceBefore = + this.properties.get("space-before.optimum").getLength().getValue(); + this.spaceAfter = + this.properties.get("space-after.optimum").getLength().getValue(); + + } + + public void addChild(FONode child) { + if ("fo:list-item-label".equals(child.getName())) { + label = (ListItemLabel)child; + } else if ("fo:list-item-body".equals(child.getName())) { + body = (ListItemBody)child; + } else if ("fo:marker".equals(child.getName())) { + // marker + } else { + // error + } + } + + public boolean generatesInlineAreas() { + return false; + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/ListItemBody.java b/src/java/org/apache/fop/fo/flow/ListItemBody.java new file mode 100644 index 000000000..77a25c0ab --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/ListItemBody.java @@ -0,0 +1,94 @@ +/* + * $Id: ListItemBody.java,v 1.21 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layoutmgr.list.Item; + +public class ListItemBody extends FObj { + + public ListItemBody(FONode parent) { + super(parent); + } + + public Item getItemLayoutManager() { + Item item = new Item(); + item.setUserAgent(getUserAgent()); + item.setFObj(this); + return item; + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + setupID(); + // this.properties.get("keep-together"); + + /* + * For calculating the lineage - The fo:list-item-body formatting object + * does not generate any areas. The fo:list-item-body formatting object + * returns the sequence of areas created by concatenating the sequences + * of areas returned by each of the children of the fo:list-item-body. + */ + + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/ListItemLabel.java b/src/java/org/apache/fop/fo/flow/ListItemLabel.java new file mode 100644 index 000000000..0080331a2 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/ListItemLabel.java @@ -0,0 +1,94 @@ +/* + * $Id: ListItemLabel.java,v 1.21 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layoutmgr.list.Item; + +public class ListItemLabel extends FObj { + + public ListItemLabel(FONode parent) { + super(parent); + } + + public Item getItemLayoutManager() { + Item itemLabel = new Item(); + itemLabel.setUserAgent(getUserAgent()); + itemLabel.setFObj(this); + return itemLabel; + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + setupID(); + // this.properties.get("keep-together"); + + /* + * For calculating the lineage - The fo:list-item-label formatting object + * does not generate any areas. The fo:list-item-label formatting object + * returns the sequence of areas created by concatenating the sequences + * of areas returned by each of the children of the fo:list-item-label. + */ + + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/Marker.java b/src/java/org/apache/fop/fo/flow/Marker.java new file mode 100644 index 000000000..06405e792 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Marker.java @@ -0,0 +1,111 @@ +/* + * $Id: Marker.java,v 1.13 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; + +/** + * Marker formatting object. + * This is the marker formatting object that handles merkers. + * This attempts to add itself to the parent formatting object. + */ +public class Marker extends FObjMixed { + + private String markerClassName; + + /** + * Create a marker fo. + * + * @param parent the parent fo node + */ + public Marker(FONode parent) { + super(parent); + } + + /** + * Handle the attributes for this marker. + * This gets the marker-class-name and attempts to add itself + * to the parent formatting object. + * + * @param attlist the attribute list + * @throws FOPException if there is an exception + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + this.markerClassName = + this.properties.get("marker-class-name").getString(); + } + + /** + * @see org.apache.fop.fo.FONode#isMarker() + */ + protected boolean isMarker() { + return true; + } + + /** + * Get the marker class name for this marker. + * + * @return the marker class name + */ + public String getMarkerClassName() { + return markerClassName; + } + + +} diff --git a/src/java/org/apache/fop/fo/flow/MultiCase.java b/src/java/org/apache/fop/fo/flow/MultiCase.java new file mode 100644 index 000000000..6730a1a1d --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/MultiCase.java @@ -0,0 +1,78 @@ +/* + * $Id: MultiCase.java,v 1.9 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; + +/** + * fo:multi-case element. + */ +public class MultiCase extends ToBeImplementedElement { + + public MultiCase(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + setupID(); + // this.properties.get("starting-state"); + // this.properties.get("case-name"); + // this.properties.get("case-title"); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/MultiProperties.java b/src/java/org/apache/fop/fo/flow/MultiProperties.java new file mode 100644 index 000000000..aac48afc6 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/MultiProperties.java @@ -0,0 +1,75 @@ +/* + * $Id: MultiProperties.java,v 1.10 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; + +/** + * fo:multi-properties element. + */ +public class MultiProperties extends ToBeImplementedElement { + + public MultiProperties(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + setupID(); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/MultiPropertySet.java b/src/java/org/apache/fop/fo/flow/MultiPropertySet.java new file mode 100644 index 000000000..3fba25228 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/MultiPropertySet.java @@ -0,0 +1,72 @@ +/* + * $Id: MultiPropertySet.java,v 1.10 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; + +/** + * fo:multi-property-set element. + */ +public class MultiPropertySet extends ToBeImplementedElement { + + public MultiPropertySet(FONode parent) { + super(parent); + } + + public void setup() { + + setupID(); + // this.properties.get("active-state"); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/MultiSwitch.java b/src/java/org/apache/fop/fo/flow/MultiSwitch.java new file mode 100644 index 000000000..e3ef64489 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/MultiSwitch.java @@ -0,0 +1,76 @@ +/* + * $Id: MultiSwitch.java,v 1.10 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; + +/** + * fo:multi-switch element. + */ +public class MultiSwitch extends ToBeImplementedElement { + + public MultiSwitch(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // this.properties.get("auto-restore"); + setupID(); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/MultiToggle.java b/src/java/org/apache/fop/fo/flow/MultiToggle.java new file mode 100644 index 000000000..b485176e4 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/MultiToggle.java @@ -0,0 +1,76 @@ +/* + * $Id: MultiToggle.java,v 1.10 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; + +/** + * fo:multi-toggle element. + */ +public class MultiToggle extends ToBeImplementedElement { + + public MultiToggle(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + setupID(); + // this.properties.get("switch-to"); + + } +} diff --git a/src/java/org/apache/fop/fo/flow/PageNumber.java b/src/java/org/apache/fop/fo/flow/PageNumber.java new file mode 100644 index 000000000..6de17c989 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/PageNumber.java @@ -0,0 +1,185 @@ +/* + * $Id: PageNumber.java,v 1.30 2003/03/05 20:38:21 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layout.TextState; +import org.apache.fop.util.CharUtilities; + +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.Word; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.area.Trait; + +public class PageNumber extends FObj { + protected FontInfo fontInfo = null; + protected FontState fontState; + + private float red; + private float green; + private float blue; + private int wrapOption; + private int whiteSpaceCollapse; + private TextState ts; + + public PageNumber(FONode parent) { + super(parent); + } + + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + fontInfo = st.getFontInfo(); + } + + public void addLayoutManager(List lms) { + setup(); + LayoutManager lm; + lm = new LeafNodeLayoutManager() { + public InlineArea get(LayoutContext context) { + // get page string from parent, build area + Word inline = new Word(); + String str = parentLM.getCurrentPageNumber(); + int width = 0; + for (int count = 0; count < str.length(); count++) { + width += CharUtilities.getCharWidth( + str.charAt(count), fontState); + } + inline.setWord(str); + inline.setIPD(width); + inline.setHeight(fontState.getAscender() + - fontState.getDescender()); + inline.setOffset(fontState.getAscender()); + + inline.addTrait(Trait.FONT_NAME, + fontState.getFontName()); + inline.addTrait(Trait.FONT_SIZE, + new Integer(fontState.getFontSize())); + + return inline; + } + + protected void offsetArea(LayoutContext context) { + curArea.setOffset(context.getBaseline()); + } + }; + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lms.add(lm); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + this.fontState = propMgr.getFontState(fontInfo); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("dominant-baseline"); + setupID(); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("score-spaces"); + // this.properties.get("text-decoration"); + // this.properties.get("text-shadow"); + // this.properties.get("text-transform"); + // this.properties.get("word-spacing"); + + ColorType c = this.properties.get("color").getColorType(); + this.red = c.getRed(); + this.green = c.getGreen(); + this.blue = c.getBlue(); + + this.wrapOption = this.properties.get("wrap-option").getEnum(); + this.whiteSpaceCollapse = + this.properties.get("white-space-collapse").getEnum(); + ts = new TextState(); + + } + +} diff --git a/src/java/org/apache/fop/fo/flow/PageNumberCitation.java b/src/java/org/apache/fop/fo/flow/PageNumberCitation.java new file mode 100644 index 000000000..3aa394272 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/PageNumberCitation.java @@ -0,0 +1,246 @@ +/* + * $Id: PageNumberCitation.java,v 1.30 2003/03/05 20:38:22 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.UnresolvedPageNumber; +import org.apache.fop.area.inline.Word; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.MarginInlineProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layout.TextState; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafNodeLayoutManager; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.util.CharUtilities; + +/** + * Page number citation. + * This inline fo is replaced with the text for a page number. + * The page number used is the page that contains the start of the + * block referenced with the ref-id attribute. + */ +public class PageNumberCitation extends FObj { + protected FontInfo fontInfo = null; + protected FontState fontState; + + private float red; + private float green; + private float blue; + private int wrapOption; + private int whiteSpaceCollapse; + private String pageNumber; + private String refId; + private TextState ts; + private InlineArea inline = null; + private boolean unresolved = false; + + public PageNumberCitation(FONode parent) { + super(parent); + } + + public void setStructHandler(StructureHandler st) { + super.setStructHandler(st); + fontInfo = st.getFontInfo(); + } + + public void addLayoutManager(List lms) { + setup(); + LayoutManager lm; + lm = new LeafNodeLayoutManager() { + public InlineArea get(LayoutContext context) { + return getInlineArea(parentLM); + } + + public void addAreas(PositionIterator posIter, + LayoutContext context) { + super.addAreas(posIter, context); + if (unresolved) { + parentLM.addUnresolvedArea(refId, + (Resolveable) inline); + } + } + + protected void offsetArea(LayoutContext context) { + curArea.setOffset(context.getBaseline()); + } + }; + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + lms.add(lm); + } + + // if id can be resolved then simply return a word, otherwise + // return a resolveable area + private InlineArea getInlineArea(LayoutProcessor parentLM) { + if (refId.equals("")) { + getLogger().error("page-number-citation must contain \"ref-id\""); + return null; + } + PageViewport page = parentLM.resolveRefID(refId); + if (page != null) { + String str = page.getPageNumber(); + // get page string from parent, build area + Word word = new Word(); + inline = word; + int width = getStringWidth(str); + word.setWord(str); + inline.setIPD(width); + inline.setHeight(fontState.getAscender() + - fontState.getDescender()); + inline.setOffset(fontState.getAscender()); + + inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); + inline.addTrait(Trait.FONT_SIZE, + new Integer(fontState.getFontSize())); + unresolved = false; + } else { + unresolved = true; + inline = new UnresolvedPageNumber(refId); + String str = "MMM"; // reserve three spaces for page number + int width = getStringWidth(str); + inline.setIPD(width); + inline.setHeight(fontState.getAscender() + - fontState.getDescender()); + inline.setOffset(fontState.getAscender()); + + inline.addTrait(Trait.FONT_NAME, fontState.getFontName()); + inline.addTrait(Trait.FONT_SIZE, + new Integer(fontState.getFontSize())); + } + return inline; + } + + protected int getStringWidth(String str) { + int width = 0; + for (int count = 0; count < str.length(); count++) { + width += CharUtilities.getCharWidth(str.charAt(count), + fontState); + } + return width; + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Font Properties + this.fontState = propMgr.getFontState(fontInfo); + + // Common Margin Properties-Inline + MarginInlineProps mProps = propMgr.getMarginInlineProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("alignment-adjust"); + // this.properties.get("alignment-baseline"); + // this.properties.get("baseline-shift"); + // this.properties.get("dominant-baseline"); + setupID(); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("letter-spacing"); + // this.properties.get("line-height"); + // this.properties.get("line-height-shift-adjustment"); + // this.properties.get("ref-id"); + // this.properties.get("score-spaces"); + // this.properties.get("text-decoration"); + // this.properties.get("text-shadow"); + // this.properties.get("text-transform"); + // this.properties.get("word-spacing"); + + ColorType c = this.properties.get("color").getColorType(); + this.red = c.getRed(); + this.green = c.getGreen(); + this.blue = c.getBlue(); + + this.wrapOption = this.properties.get("wrap-option").getEnum(); + this.whiteSpaceCollapse = + this.properties.get("white-space-collapse").getEnum(); + + this.refId = this.properties.get("ref-id").getString(); + + if (this.refId.equals("")) { + //throw new FOPException("page-number-citation must contain \"ref-id\""); + } + + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/RetrieveMarker.java b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java new file mode 100644 index 000000000..3abc308d5 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/RetrieveMarker.java @@ -0,0 +1,109 @@ +/* + * $Id: RetrieveMarker.java,v 1.13 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; +import org.apache.fop.layoutmgr.RetrieveMarkerLayoutManager; +import org.xml.sax.Attributes; + +import java.util.List; + +/** + * The retrieve-marker formatting object. + * This will create a layout manager that will retrieve + * a marker based on the information. + */ +public class RetrieveMarker extends FObjMixed { + + private String retrieveClassName; + private int retrievePosition; + private int retrieveBoundary; + + /** + * Create a retrieve marker object. + * + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RetrieveMarker(FONode parent) { + super(parent); + } + + /** + * Handle the attributes for the retrieve-marker. + * + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + this.retrieveClassName = + this.properties.get("retrieve-class-name").getString(); + this.retrievePosition = + this.properties.get("retrieve-position").getEnum(); + this.retrieveBoundary = + this.properties.get("retrieve-boundary").getEnum(); + } + + /** + * @see org.apache.fop.fo.FObj#addLayoutManager(List) + */ + public void addLayoutManager(List lms) { + RetrieveMarkerLayoutManager rmlm; + rmlm = new RetrieveMarkerLayoutManager(retrieveClassName, + retrievePosition, + retrieveBoundary); + rmlm.setUserAgent(getUserAgent()); + rmlm.setFObj(this); + lms.add(rmlm); + } +} diff --git a/src/java/org/apache/fop/fo/flow/StaticContent.java b/src/java/org/apache/fop/fo/flow/StaticContent.java new file mode 100644 index 000000000..da7d4df82 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/StaticContent.java @@ -0,0 +1,90 @@ +/* + * $Id: StaticContent.java,v 1.26 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.apps.FOPException; +import org.apache.fop.layoutmgr.StaticContentLayoutManager; + +public class StaticContent extends Flow { + + public StaticContent(FONode parent) { + super(parent); + } + + public void setup() { + + } + + // flowname checking is more stringient for static content currently + protected void setFlowName(String name) throws FOPException { + if (name == null || name.equals("")) { + throw new FOPException("A 'flow-name' is required for " + + getName() + "."); + } else { + super.setFlowName(name); + } + + } + + private StaticContentLayoutManager lm; + + public StaticContentLayoutManager getLayoutManager() { + if (lm == null) { + lm = new StaticContentLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.setFObj(this); + } + return lm; + } + +} diff --git a/src/java/org/apache/fop/fo/flow/Table.java b/src/java/org/apache/fop/fo/flow/Table.java new file mode 100644 index 000000000..8d672623f --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Table.java @@ -0,0 +1,208 @@ +/* + * $Id: Table.java,v 1.50 2003/03/05 20:38:21 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.ArrayList; +import java.util.List; + +// FOP +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.LengthRange; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.TableLayout; +import org.apache.fop.fo.properties.TableOmitFooterAtBreak; +import org.apache.fop.fo.properties.TableOmitHeaderAtBreak; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.table.TableLayoutManager; + +public class Table extends FObj { + private static final int MINCOLWIDTH = 10000; // 10pt + + protected ArrayList columns = null; + private TableBody tableHeader = null; + private TableBody tableFooter = null; + private boolean omitHeaderAtBreak = false; + private boolean omitFooterAtBreak = false; + + private int breakBefore; + private int breakAfter; + private int spaceBefore; + private int spaceAfter; + private ColorType backgroundColor; + private LengthRange ipd; + private int height; + + private boolean bAutoLayout = false; + private int contentWidth = 0; // Sum of column widths + /** Optimum inline-progression-dimension */ + private int optIPD; + /** Minimum inline-progression-dimension */ + private int minIPD; + /** Maximum inline-progression-dimension */ + private int maxIPD; + + public Table(FONode parent) { + super(parent); + } + + protected void addChild(FONode child) { + if (child.getName().equals("fo:table-column")) { + if (columns == null) { + columns = new ArrayList(); + } + columns.add(((TableColumn)child).getLayoutManager()); + } else if (child.getName().equals("fo:table-footer")) { + tableFooter = (TableBody)child; + } else if (child.getName().equals("fo:table-header")) { + tableHeader = (TableBody)child; + } else { + // add bodies + super.addChild(child); + } + } + + /** + * Return a LayoutManager responsible for laying out this FObj's content. + * Must override in subclasses if their content can be laid out. + */ + public void addLayoutManager(List list) { + TableLayoutManager tlm = new TableLayoutManager(); + tlm.setUserAgent(getUserAgent()); + tlm.setFObj(this); + tlm.setColumns(columns); + if (tableHeader != null) { + tlm.setTableHeader(tableHeader.getLayoutManager()); + } + if (tableFooter != null) { + tlm.setTableFooter(tableFooter.getLayoutManager()); + } + list.add(tlm); + } + + public void setup() { + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + // this.properties.get("block-progression-dimension"); + // this.properties.get("border-after-precendence"); + // this.properties.get("border-before-precedence"); + // this.properties.get("border-collapse"); + // this.properties.get("border-end-precendence"); + // this.properties.get("border-separation"); + // this.properties.get("border-start-precendence"); + // this.properties.get("break-after"); + // this.properties.get("break-before"); + setupID(); + // this.properties.get("inline-progression-dimension"); + // this.properties.get("height"); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + // this.properties.get("table-layout"); + // this.properties.get("table-omit-footer-at-break"); + // this.properties.get("table-omit-header-at-break"); + // this.properties.get("width"); + // this.properties.get("writing-mode"); + + this.breakBefore = this.properties.get("break-before").getEnum(); + this.breakAfter = this.properties.get("break-after").getEnum(); + this.spaceBefore = this.properties.get( + "space-before.optimum").getLength().getValue(); + this.spaceAfter = this.properties.get( + "space-after.optimum").getLength().getValue(); + this.backgroundColor = + this.properties.get("background-color").getColorType(); + this.ipd = this.properties.get( + "inline-progression-dimension").getLengthRange(); + this.height = this.properties.get("height").getLength().getValue(); + this.bAutoLayout = (this.properties.get( + "table-layout").getEnum() == TableLayout.AUTO); + + this.omitHeaderAtBreak = this.properties.get( + "table-omit-header-at-break").getEnum() + == TableOmitHeaderAtBreak.TRUE; + this.omitFooterAtBreak = this.properties.get( + "table-omit-footer-at-break").getEnum() + == TableOmitFooterAtBreak.TRUE; + + } + + public boolean generatesInlineAreas() { + return false; + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableAndCaption.java b/src/java/org/apache/fop/fo/flow/TableAndCaption.java new file mode 100644 index 000000000..fd03bc5bd --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableAndCaption.java @@ -0,0 +1,107 @@ +/* + * $Id: TableAndCaption.java,v 1.11 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.RelativePositionProps; + +/** + * fo:table-and-caption element. + */ +public class TableAndCaption extends ToBeImplementedElement { + + public TableAndCaption(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Margin Properties-Block + MarginProps mProps = propMgr.getMarginProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("caption-side"); + setupID(); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + + } + + public boolean generatesInlineAreas() { + return false; + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableBody.java b/src/java/org/apache/fop/fo/flow/TableBody.java new file mode 100644 index 000000000..ce9e68cf5 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableBody.java @@ -0,0 +1,125 @@ +/* + * $Id: TableBody.java,v 1.48 2003/03/05 20:38:22 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; + +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.table.Body; + +public class TableBody extends FObj { + + private int spaceBefore; + private int spaceAfter; + private ColorType backgroundColor; + + public TableBody(FONode parent) { + super(parent); + } + + /** + * Return a LayoutManager responsible for laying out this FObj's content. + * Must override in subclasses if their content can be laid out. + */ + public void addLayoutManager(List list) { + list.add(getLayoutManager()); + } + + public Body getLayoutManager() { + Body blm = new Body(); + blm.setUserAgent(getUserAgent()); + blm.setFObj(this); + return blm; + } + + public void setup() throws FOPException { + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = + propMgr.getRelativePositionProps(); + + setupID(); + + this.spaceBefore = this.properties.get( + "space-before.optimum").getLength().getValue(); + this.spaceAfter = this.properties.get( + "space-after.optimum").getLength().getValue(); + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableCaption.java b/src/java/org/apache/fop/fo/flow/TableCaption.java new file mode 100644 index 000000000..6d1dd078a --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableCaption.java @@ -0,0 +1,100 @@ +/* + * $Id: TableCaption.java,v 1.10 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.ToBeImplementedElement; +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.RelativePositionProps; + +/** + * fo:table-caption element. + */ +public class TableCaption extends ToBeImplementedElement { + + public TableCaption(FONode parent) { + super(parent); + } + + public void setup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("block-progression-dimension"); + // this.properties.get("height"); + setupID(); + // this.properties.get("inline-progression-dimension"); + // this.properties.get("keep-togethe"); + // this.properties.get("width"); + + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableCell.java b/src/java/org/apache/fop/fo/flow/TableCell.java new file mode 100644 index 000000000..b2dcc4b93 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableCell.java @@ -0,0 +1,358 @@ +/* + * $Id: TableCell.java,v 1.52 2003/03/05 20:38:22 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.BorderCollapse; +import org.apache.fop.fo.properties.DisplayAlign; + +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.table.Cell; + + +public class TableCell extends FObj { + + // private int spaceBefore; + // private int spaceAfter; + private ColorType backgroundColor; + + private int numColumnsSpanned; + private int numRowsSpanned; + private int iColNumber = -1; // uninitialized + + /** + * Offset of content rectangle in inline-progression-direction, + * relative to table. + */ + protected int startOffset; + + /** + * Dimension of allocation rectangle in inline-progression-direction, + * determined by the width of the column(s) occupied by the cell + */ + protected int width; + + /** + * Offset of content rectangle, in block-progression-direction, + * relative to the row. + */ + protected int beforeOffset = 0; + + /** + * Offset of content rectangle, in inline-progression-direction, + * relative to the column start edge. + */ + protected int startAdjust = 0; + + /** + * Adjust to theoretical column width to obtain content width + * relative to the column start edge. + */ + protected int widthAdjust = 0; + + /* For collapsed border style */ + protected int borderHeight = 0; + + /** Minimum ontent height of cell. */ + protected int minCellHeight = 0; + /** Height of cell */ + protected int height = 0; + /** Ypos of cell ??? */ + protected int top; + protected int verticalAlign; + protected boolean bRelativeAlign = false; + + // boolean setup = false; + private boolean bSepBorders = true; + + /** + * Set to true if all content completely laid out. + */ + private boolean bDone = false; + + /** + * Border separation value in the block-progression dimension. + * Used in calculating cells height. + */ + private int borderSeparation = 0; + + public TableCell(FONode parent) { + super(parent); + } + + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + doSetup(); // init some basic property values + } + + /** + */ + public void addLayoutManager(List list) { + Cell clm = new Cell(); + clm.setUserAgent(getUserAgent()); + clm.setFObj(this); + list.add(clm); + } + + /** + * Set position relative to table (set by body?) + */ + public void setStartOffset(int offset) { + startOffset = offset; + } + + // Initially same as the column width containg this cell or the + // sum of the spanned columns if numColumnsSpanned > 1 + public void setWidth(int width) { + this.width = width; + } + + public int getColumnNumber() { + return iColNumber; + } + + public int getNumColumnsSpanned() { + return numColumnsSpanned; + } + + public int getNumRowsSpanned() { + return numRowsSpanned; + } + + public void doSetup() { + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("border-after-precedence"); + // this.properties.get("border-before-precendence"); + // this.properties.get("border-end-precendence"); + // this.properties.get("border-start-precendence"); + // this.properties.get("block-progression-dimension"); + // this.properties.get("column-number"); + // this.properties.get("display-align"); + // this.properties.get("relative-align"); + // this.properties.get("empty-cells"); + // this.properties.get("ends-row"); + // this.properties.get("height"); + setupID(); + // this.properties.get("number-columns-spanned"); + // this.properties.get("number-rows-spanned"); + // this.properties.get("starts-row"); + // this.properties.get("width"); + + this.iColNumber = + properties.get("column-number").getNumber().intValue(); + if (iColNumber < 0) { + iColNumber = 0; + } + this.numColumnsSpanned = + this.properties.get("number-columns-spanned").getNumber().intValue(); + if (numColumnsSpanned < 1) { + numColumnsSpanned = 1; + } + this.numRowsSpanned = + this.properties.get("number-rows-spanned").getNumber().intValue(); + if (numRowsSpanned < 1) { + numRowsSpanned = 1; + } + + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + bSepBorders = (this.properties.get("border-collapse").getEnum() + == BorderCollapse.SEPARATE); + + calcBorders(propMgr.getBorderAndPadding()); + + // Vertical cell alignment + verticalAlign = this.properties.get("display-align").getEnum(); + if (verticalAlign == DisplayAlign.AUTO) { + // Depends on all cells starting in row + bRelativeAlign = true; + verticalAlign = this.properties.get("relative-align").getEnum(); + } else { + bRelativeAlign = false; // Align on a per-cell basis + } + + this.minCellHeight = + this.properties.get("height").getLength().getValue(); + } + + /** + * Calculate cell border and padding, including offset of content + * rectangle from the theoretical grid position. + */ + private void calcBorders(BorderAndPadding bp) { + if (this.bSepBorders) { + /* + * Easy case. + * Cell border is the property specified directly on cell. + * Offset content rect by half the border-separation value, + * in addition to the border and padding values. Note: + * border-separate should only be specified on the table object, + * but it inherits. + */ + int iSep = properties.get( + "border-separation.inline-progression-direction").getLength().getValue(); + this.startAdjust = iSep / 2 + bp.getBorderLeftWidth(false) + + bp.getPaddingLeft(false); + /* + * int contentOffset = iSep + bp.getBorderStartWidth(false) + + * bp.getPaddingStart(false); + */ + this.widthAdjust = startAdjust + iSep - iSep / 2 + + bp.getBorderRightWidth(false) + + bp.getPaddingRight(false); + // bp.getBorderEndWidth(false) + bp.getPaddingEnd(false); + // Offset of content rectangle in the block-progression direction + borderSeparation = properties.get( + "border-separation.block-progression-direction").getLength().getValue(); + this.beforeOffset = borderSeparation / 2 + + bp.getBorderTopWidth(false) + + bp.getPaddingTop(false); + // bp.getBorderBeforeWidth(false) + bp.getPaddingBefore(false); + + } else { + // System.err.println("Collapse borders"); + /* + * Hard case. + * Cell border is combination of other cell borders, or table + * border for edge cells. Also seems to border values specified + * on row and column FO in the table (if I read CR correclty.) + */ + + // Set up before and after borders, taking into account row + // and table border properties. + // ??? What about table-body, header,footer + + /* + * We can't calculate before and after because we aren't sure + * whether this row will be the first or last in its area, due + * to redoing break decisions (at least in the "new" architecture.) + * So in the general case, we will calculate two possible values: + * the first/last one and the "middle" one. + * Example: border-before + * 1. If the cell is in the first row in the first table body, it + * will combine with the last row of the header, or with the + * top (before) table border if there is no header. + * 2. Otherwise there are two cases: + * a. the row is first in its (non-first) Area. + * The border can combine with either: + * i. the last row of table-header and its cells, or + * ii. the table before border (no table-header or it is + * omitted on non-first Areas). + * b. the row isn't first in its Area. + * The border combines with the border of the previous + * row and the cells which end in that row. + */ + + /* + * if-first + * Calculate the effective border of the cell before-border, + * it's parent row before-border, the last header row after-border, + * the after border of the cell(s) which end in the last header + * row. + */ + /* + * if-not-first + * Calculate the effective border of the cell before-border, + * it's parent row before-border, the previous row after-border, + * the after border of the cell(s) which end in the previous + * row. + */ + + + /* ivan demakov */ + int borderStart = bp.getBorderLeftWidth(false); + int borderEnd = bp.getBorderRightWidth(false); + int borderBefore = bp.getBorderTopWidth(false); + int borderAfter = bp.getBorderBottomWidth(false); + + this.startAdjust = borderStart / 2 + bp.getPaddingLeft(false); + + this.widthAdjust = startAdjust + borderEnd / 2 + + bp.getPaddingRight(false); + this.beforeOffset = borderBefore / 2 + bp.getPaddingTop(false); + // Half border height to fix overestimate of area size! + this.borderHeight = (borderBefore + borderAfter) / 2; + } + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableColumn.java b/src/java/org/apache/fop/fo/flow/TableColumn.java new file mode 100644 index 000000000..956f11758 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableColumn.java @@ -0,0 +1,151 @@ +/* + * $Id: TableColumn.java,v 1.29 2003/03/05 20:38:21 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.Length; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.Property; + +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layoutmgr.LayoutManager; +import org.apache.fop.layoutmgr.table.Column; + +public class TableColumn extends FObj { + + private ColorType backgroundColor; + + private Length columnWidthPropVal; + private int columnWidth; + private int columnOffset; + private int numColumnsRepeated; + private int iColumnNumber; + + private boolean setup = false; + + public TableColumn(FONode parent) { + super(parent); + } + + public LayoutManager getLayoutManager() { + doSetup(); + Column clm = new Column(); + clm.setUserAgent(getUserAgent()); + clm.setFObj(this); + return clm; + } + + public Length getColumnWidthAsLength() { + return columnWidthPropVal; + } + + public int getColumnWidth() { + return columnWidth; + } + + /** + * Set the column width value in base units which overrides the + * value from the column-width Property. + */ + public void setColumnWidth(int columnWidth) { + this.columnWidth = columnWidth; + } + + public int getColumnNumber() { + return iColumnNumber; + } + + public int getNumColumnsRepeated() { + return numColumnsRepeated; + } + + public void doSetup() { + + // Common Border, Padding, and Background Properties + // only background apply, border apply if border-collapse + // is collapse. + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // this.properties.get("column-width"); + // this.properties.get("number-columns-repeated"); + // this.properties.get("number-columns-spanned"); + // this.properties.get("visibility"); + + iColumnNumber = properties.get("column-number").getNumber().intValue(); + + numColumnsRepeated = + properties.get("number-columns-repeated").getNumber().intValue(); + + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + Property prop = this.properties.get("column-width"); + if (prop != null) { + columnWidthPropVal = properties.get("column-width").getLength(); + + // This won't include resolved table-units or % values yet. + columnWidth = columnWidthPropVal.getValue(); + } else { + columnWidth = 300000; + } + + // initialize id + setupID(); + + setup = true; + } + +} + diff --git a/src/java/org/apache/fop/fo/flow/TableFooter.java b/src/java/org/apache/fop/fo/flow/TableFooter.java new file mode 100644 index 000000000..17f5008dd --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableFooter.java @@ -0,0 +1,62 @@ +/* + * $Id: TableFooter.java,v 1.8 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; + +public class TableFooter extends TableBody { + + public TableFooter(FONode parent) { + super(parent); + } + +} diff --git a/src/java/org/apache/fop/fo/flow/TableHeader.java b/src/java/org/apache/fop/fo/flow/TableHeader.java new file mode 100644 index 000000000..d9b725874 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableHeader.java @@ -0,0 +1,62 @@ +/* + * $Id: TableHeader.java,v 1.6 2003/03/06 11:36:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; + +public class TableHeader extends TableBody { + + public TableHeader(FONode parent) { + super(parent); + } + +} diff --git a/src/java/org/apache/fop/fo/flow/TableRow.java b/src/java/org/apache/fop/fo/flow/TableRow.java new file mode 100644 index 000000000..42a058b6a --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/TableRow.java @@ -0,0 +1,157 @@ +/* + * $Id: TableRow.java,v 1.61 2003/03/05 20:38:20 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// Java +import java.util.List; + +// FOP +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.KeepValue; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.properties.Constants; + +import org.apache.fop.layout.AccessibilityProps; +import org.apache.fop.layout.AuralProps; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.RelativePositionProps; +import org.apache.fop.layoutmgr.table.Row; + +public class TableRow extends FObj { + + private boolean setup = false; + + private int breakAfter; + private ColorType backgroundColor; + + private KeepValue keepWithNext; + private KeepValue keepWithPrevious; + private KeepValue keepTogether; + + private int minHeight = 0; // force row height + + public TableRow(FONode parent) { + super(parent); + } + + /** + */ + public void addLayoutManager(List list) { + Row rlm = new Row(); + rlm.setUserAgent(getUserAgent()); + rlm.setFObj(this); + list.add(rlm); + } + + public KeepValue getKeepWithPrevious() { + return keepWithPrevious; + } + + public void doSetup() { + + // Common Accessibility Properties + AccessibilityProps mAccProps = propMgr.getAccessibilityProps(); + + // this.properties.get("block-progression-dimension"); + + // Common Aural Properties + AuralProps mAurProps = propMgr.getAuralProps(); + + // Common Border, Padding, and Background Properties + // only background apply, border apply if border-collapse + // is collapse. + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + + // Common Relative Position Properties + RelativePositionProps mRelProps = propMgr.getRelativePositionProps(); + + // this.properties.get("break-before"); + // this.properties.get("break-after"); + setupID(); + // this.properties.get("height"); + // this.properties.get("keep-together"); + // this.properties.get("keep-with-next"); + // this.properties.get("keep-with-previous"); + + + this.breakAfter = this.properties.get("break-after").getEnum(); + this.backgroundColor = + this.properties.get("background-color").getColorType(); + + this.keepTogether = getKeepValue("keep-together.within-column"); + this.keepWithNext = getKeepValue("keep-with-next.within-column"); + this.keepWithPrevious = + getKeepValue("keep-with-previous.within-column"); + + this.minHeight = this.properties.get("height").getLength().getValue(); + setup = true; + } + + private KeepValue getKeepValue(String sPropName) { + Property p = this.properties.get(sPropName); + Number n = p.getNumber(); + if (n != null) { + return new KeepValue(KeepValue.KEEP_WITH_VALUE, n.intValue()); + } + switch (p.getEnum()) { + case Constants.ALWAYS: + return new KeepValue(KeepValue.KEEP_WITH_ALWAYS, 0); + case Constants.AUTO: + default: + return new KeepValue(KeepValue.KEEP_WITH_AUTO, 0); + } + } +} + diff --git a/src/java/org/apache/fop/fo/flow/Wrapper.java b/src/java/org/apache/fop/fo/flow/Wrapper.java new file mode 100644 index 000000000..d3e176db6 --- /dev/null +++ b/src/java/org/apache/fop/fo/flow/Wrapper.java @@ -0,0 +1,76 @@ +/* + * $Id: Wrapper.java,v 1.9 2003/03/06 11:36:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.flow; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObjMixed; + +/** + * Implementation for fo:wrapper formatting object. + * The wrapper object serves as + * a property holder for it's children objects. + * + * Content: (#PCDATA|%inline;|%block;)* + * Properties: id + */ +public class Wrapper extends FObjMixed { + + public Wrapper(FONode parent) { + super(parent); + } + + protected boolean containsMarkers() { + return true; + } + +} + diff --git a/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java b/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java new file mode 100644 index 000000000..acc1f72fe --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/ConditionalPageMasterReference.java @@ -0,0 +1,200 @@ +/* + * $Id: ConditionalPageMasterReference.java,v 1.12 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.properties.BlankOrNotBlank; +import org.apache.fop.fo.properties.OddOrEven; +import org.apache.fop.fo.properties.PagePosition; +import org.apache.fop.apps.FOPException; + +/** + * A conditional-page-master-reference formatting object. + * This is a reference to a page master with a set of conditions. + * The conditions must be satisfied for the referenced master to + * be used. + * This element is must be the child of a repeatable-page-master-alternatives + * element. + */ +public class ConditionalPageMasterReference extends FObj { + + private RepeatablePageMasterAlternatives repeatablePageMasterAlternatives; + + private String masterName; + + private int pagePosition; + private int oddOrEven; + private int blankOrNotBlank; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public ConditionalPageMasterReference(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + if (getProperty("master-reference") != null) { + setMasterName(getProperty("master-reference").getString()); + } + + validateParent(parent); + + this.pagePosition = this.properties.get("page-position").getEnum(); + this.oddOrEven = this.properties.get("odd-or-even").getEnum(); + this.blankOrNotBlank = this.properties.get("blank-or-not-blank").getEnum(); + } + + /** + * Sets the master name. + * @param masterName name for the master + */ + protected void setMasterName(String masterName) { + this.masterName = masterName; + } + + /** + * Returns the "master-name" attribute of this page master reference + * @return the master name + */ + public String getMasterName() { + return masterName; + } + + /** + * Check if the conditions for this reference are met. + * checks the page number and emptyness to determine if this + * matches. + * @param isOddPage True if page number odd + * @param isFirstPage True if page is first page + * @param isBlankPage True if page is blank + * @return True if the conditions for this reference are met + */ + protected boolean isValid(boolean isOddPage, + boolean isFirstPage, + boolean isBlankPage) { + // page-position + if (isFirstPage) { + if (pagePosition == PagePosition.REST) { + return false; + } else if (pagePosition == PagePosition.LAST) { + // how the hell do you know at this point? + getLogger().debug("LAST PagePosition NYI"); + return false; + } + } else { + if (pagePosition == PagePosition.FIRST) { + return false; + } else if (pagePosition == PagePosition.LAST) { + // how the hell do you know at this point? + getLogger().debug("LAST PagePosition NYI"); + // potentially valid, don't return + } + } + + // odd-or-even + if (isOddPage) { + if (oddOrEven == OddOrEven.EVEN) { + return false; + } + } else { + if (oddOrEven == OddOrEven.ODD) { + return false; + } + } + + // blank-or-not-blank + if (isBlankPage) { + if (blankOrNotBlank == BlankOrNotBlank.NOT_BLANK) { + return false; + } + } else { + if (blankOrNotBlank == BlankOrNotBlank.BLANK) { + return false; + } + } + return true; + } + + /** + * Check that the parent is the right type of formatting object + * repeatable-page-master-alternatives. + * @param parent parent node + * @throws FOPException If the parent is invalid + */ + protected void validateParent(FONode parent) throws FOPException { + if (parent.getName().equals("fo:repeatable-page-master-alternatives")) { + this.repeatablePageMasterAlternatives = + (RepeatablePageMasterAlternatives)parent; + + if (getMasterName() == null) { + getLogger().warn("single-page-master-reference" + + "does not have a master-name and so is being ignored"); + } else { + this.repeatablePageMasterAlternatives.addConditionalPageMasterReference(this); + } + } else { + throw new FOPException("fo:conditional-page-master-reference must be child " + + "of fo:repeatable-page-master-alternatives, not " + + parent.getName()); + } + } + +} diff --git a/src/java/org/apache/fop/fo/pagination/LayoutMasterSet.java b/src/java/org/apache/fop/fo/pagination/LayoutMasterSet.java new file mode 100644 index 000000000..980bf51ea --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/LayoutMasterSet.java @@ -0,0 +1,222 @@ +/* + * $Id: LayoutMasterSet.java,v 1.19 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.util.Iterator; +import java.util.Map; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.apps.FOPException; + +/** + * The layout-master-set formatting object. + * This class maintains the set of simple page master and + * page sequence masters. + * The masters are stored so that the page sequence can obtain + * the required page master to create a page. + * The page sequence masters can be reset as they hold state + * information for a page sequence. + */ +public class LayoutMasterSet extends FObj { + + private Map simplePageMasters; + private Map pageSequenceMasters; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public LayoutMasterSet(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + if (parent.getName().equals("fo:root")) { + Root root = (Root)parent; + root.setLayoutMasterSet(this); + } else { + throw new FOPException("fo:layout-master-set must be child of fo:root, not " + + parent.getName()); + } + + this.simplePageMasters = new java.util.HashMap(); + this.pageSequenceMasters = new java.util.HashMap(); + } + + /** + * Add a simple page master. + * The name is checked to throw an error if already added. + * @param simplePageMaster simple-page-master to add + * @throws FOPException if there's a problem with name uniqueness + */ + protected void addSimplePageMaster(SimplePageMaster simplePageMaster) + throws FOPException { + // check against duplication of master-name + if (existsName(simplePageMaster.getMasterName())) { + throw new FOPException("'master-name' (" + + simplePageMaster.getMasterName() + + ") must be unique " + + "across page-masters and page-sequence-masters"); + } + this.simplePageMasters.put(simplePageMaster.getMasterName(), + simplePageMaster); + } + + /** + * Get a simple page master by name. + * This is used by the page sequence to get a page master for + * creating pages. + * @param masterName the name of the page master + * @return the requested simple-page-master + */ + public SimplePageMaster getSimplePageMaster(String masterName) { + return (SimplePageMaster)this.simplePageMasters.get(masterName); + } + + /** + * Add a page sequence master. + * The name is checked to throw an error if already added. + * @param masterName name for the master + * @param pageSequenceMaster PageSequenceMaster instance + * @throws FOPException if there's a problem with name uniqueness + */ + protected void addPageSequenceMaster(String masterName, + PageSequenceMaster pageSequenceMaster) + throws FOPException { + // check against duplication of master-name + if (existsName(masterName)) { + throw new FOPException("'master-name' (" + masterName + + ") must be unique " + + "across page-masters and page-sequence-masters"); + } + this.pageSequenceMasters.put(masterName, pageSequenceMaster); + } + + /** + * Get a page sequence master by name. + * This is used by the page sequence to get a page master for + * creating pages. + * @param masterName name of the master + * @return the requested PageSequenceMaster instance + */ + public PageSequenceMaster getPageSequenceMaster(String masterName) { + return (PageSequenceMaster)this.pageSequenceMasters.get(masterName); + } + + private boolean existsName(String masterName) { + if (simplePageMasters.containsKey(masterName) + || pageSequenceMasters.containsKey(masterName)) { + return true; + } else { + return false; + } + } + + /** + * Section 7.33.15: check to see that if a region-name is a + * duplicate, that it maps to the same region-class. + * @throws FOPException if there's a name duplication + */ + protected void checkRegionNames() throws FOPException { + Map allRegions = new java.util.HashMap(); + for (Iterator spm = simplePageMasters.values().iterator(); + spm.hasNext();) { + SimplePageMaster simplePageMaster = + (SimplePageMaster)spm.next(); + Map spmRegions = simplePageMaster.getRegions(); + for (Iterator e = spmRegions.values().iterator(); + e.hasNext();) { + Region region = (Region)e.next(); + if (allRegions.containsKey(region.getRegionName())) { + String localClass = + (String)allRegions.get(region.getRegionName()); + if (!localClass.equals(region.getRegionClass())) { + throw new FOPException("Duplicate region-names (" + + region.getRegionName() + + ") must map " + + "to the same region-class (" + + localClass + "!=" + + region.getRegionClass() + + ")"); + } + } + allRegions.put(region.getRegionName(), + region.getRegionClass()); + } + } + } + + /** + * Checks whether or not a region name exists in this master set. + * @param regionName name of the region + * @return true when the region name specified has a region in this LayoutMasterSet + */ + protected boolean regionNameExists(String regionName) { + for (Iterator e = simplePageMasters.values().iterator(); + e.hasNext();) { + if (((SimplePageMaster)e.next()).regionNameExists(regionName)) { + return true; + } + } + return false; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/PageMasterReference.java b/src/java/org/apache/fop/fo/pagination/PageMasterReference.java new file mode 100644 index 000000000..bb61e279d --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/PageMasterReference.java @@ -0,0 +1,120 @@ +/* + * $Id: PageMasterReference.java,v 1.12 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// SAX +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.apps.FOPException; + +/** + * Base PageMasterReference class. Provides implementation for handling the + * master-reference attribute and containment within a PageSequenceMaster + */ +public abstract class PageMasterReference extends FObj + implements SubSequenceSpecifier { + + private String masterName; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public PageMasterReference(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + if (getProperty("master-reference") != null) { + this.masterName = getProperty("master-reference").getString(); + } + validateParent(parent); + } + + + /** + * Returns the "master-reference" attribute of this page master reference + * @return the name of the page master + */ + public String getMasterName() { + return masterName; + } + + /** + * Checks that the parent is the right element. The default implementation + * checks for fo:page-sequence-master. + * @param parent parent node + * @throws FOPException If the parent is invalid. + */ + protected void validateParent(FONode parent) throws FOPException { + if (parent.getName().equals("fo:page-sequence-master")) { + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; + + if (getMasterName() == null) { + getLogger().warn(getName() + + " does not have a master-reference and so is being ignored"); + } else { + pageSequenceMaster.addSubsequenceSpecifier(this); + } + } else { + throw new FOPException(getName() + " must be" + + "child of fo:page-sequence-master, not " + + parent.getName()); + } + } + +} diff --git a/src/java/org/apache/fop/fo/pagination/PageNumberGenerator.java b/src/java/org/apache/fop/fo/pagination/PageNumberGenerator.java new file mode 100644 index 000000000..55706f2b1 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/PageNumberGenerator.java @@ -0,0 +1,208 @@ +/* + * $Id: PageNumberGenerator.java,v 1.8 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; + +/** + * This class uses the 'format', 'groupingSeparator', 'groupingSize', + * and 'letterValue' properties on fo:page-sequence to return a String + * corresponding to the supplied integer page number. + */ +public class PageNumberGenerator extends AbstractLogEnabled { + + private String format; + private char groupingSeparator; + private int groupingSize; + private int letterValue; + + // constants + private static final int DECIMAL = 1; // '0*1' + private static final int LOWERALPHA = 2; // 'a' + private static final int UPPERALPHA = 3; // 'A' + private static final int LOWERROMAN = 4; // 'i' + private static final int UPPERROMAN = 5; // 'I' + + // flags + private int formatType = DECIMAL; + private int minPadding = 0; // for decimal formats + + // preloaded strings of zeros + private String zeros[] = { + "", "0", "00", "000", "0000", "00000" + }; + + /** + * Main constructor. For further information on the parameters see the XSLT + * specs (Number to String Conversion Attributes). + * @param format format for the page number + * @param groupingSeparator grouping separator + * @param groupingSize grouping size + * @param letterValue letter value + */ + public PageNumberGenerator(String format, char groupingSeparator, + int groupingSize, int letterValue) { + this.format = format; + this.groupingSeparator = groupingSeparator; + this.groupingSize = groupingSize; + this.letterValue = letterValue; + + // the only accepted format strings are currently '0*1' 'a', 'A', 'i' + // and 'I' + int fmtLen = format.length(); + if (fmtLen == 1) { + if (format.equals("1")) { + formatType = DECIMAL; + minPadding = 0; + } else if (format.equals("a")) { + formatType = LOWERALPHA; + } else if (format.equals("A")) { + formatType = UPPERALPHA; + } else if (format.equals("i")) { + formatType = LOWERROMAN; + } else if (format.equals("I")) { + formatType = UPPERROMAN; + } else { + // token not handled + //getLogger().debug("'format' token not recognized; using '1'"); + formatType = DECIMAL; + minPadding = 0; + } + } else { + // only accepted token is '0+1'at this stage. Because of the + // wonderful regular expression support in Java, we will resort to a + // loop + for (int i = 0; i < fmtLen - 1; i++) { + if (format.charAt(i) != '0') { + //getLogger().debug("'format' token not recognized; using '1'"); + formatType = DECIMAL; + minPadding = 0; + } else { + minPadding = fmtLen - 1; + } + } + } + } + + /** + * Formats a page number. + * @param number page number to format + * @return the formatted page number as a String + */ + public String makeFormattedPageNumber(int number) { + String pn = null; + if (formatType == DECIMAL) { + pn = Integer.toString(number); + if (minPadding >= pn.length()) { + int nz = minPadding - pn.length() + 1; + pn = zeros[nz] + pn; + } + } else if ((formatType == LOWERROMAN) || (formatType == UPPERROMAN)) { + pn = makeRoman(number); + if (formatType == UPPERROMAN) { + pn = pn.toUpperCase(); + } + } else { + // alphabetic + pn = makeAlpha(number); + if (formatType == UPPERALPHA) { + pn = pn.toUpperCase(); + } + } + return pn; + } + + private String makeRoman(int num) { + int arabic[] = { + 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 + }; + String roman[] = { + "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", + "i" + }; + + int i = 0; + StringBuffer romanNumber = new StringBuffer(); + + while (num > 0) { + while (num >= arabic[i]) { + num = num - arabic[i]; + romanNumber.append(roman[i]); + } + i = i + 1; + } + return romanNumber.toString(); + } + + private String makeAlpha(int num) { + String letters = "abcdefghijklmnopqrstuvwxyz"; + StringBuffer alphaNumber = new StringBuffer(); + + int base = 26; + int rem = 0; + + num--; + if (num < base) { + alphaNumber.append(letters.charAt(num)); + } else { + while (num >= base) { + rem = num % base; + alphaNumber.append(letters.charAt(rem)); + num = num / base; + } + alphaNumber.append(letters.charAt(num - 1)); + } + return alphaNumber.reverse().toString(); + } + +} + diff --git a/src/java/org/apache/fop/fo/pagination/PageSequence.java b/src/java/org/apache/fop/fo/pagination/PageSequence.java new file mode 100644 index 000000000..a2bbd82a0 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/PageSequence.java @@ -0,0 +1,807 @@ +/* + * $Id: PageSequence.java,v 1.61 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.Title; +import org.apache.fop.fo.flow.Flow; +import org.apache.fop.fo.flow.StaticContent; +import org.apache.fop.layout.PageMaster; +import org.apache.fop.area.AreaTree; +import org.apache.fop.area.PageViewport; +import org.apache.fop.apps.FOPException; + +import org.apache.fop.layoutmgr.PageLayoutManager; + +// Java +import java.util.HashMap; + +import org.xml.sax.Attributes; + +/** + * This provides pagination of flows onto pages. Much of the + * logic for paginating flows is contained in this class. + * The main entry point is the format method. + */ +public class PageSequence extends FObj { + // + // intial-page-number types + // + private static final int EXPLICIT = 0; + private static final int AUTO = 1; + private static final int AUTO_EVEN = 2; + private static final int AUTO_ODD = 3; + + // + // associations + // + /** + * The parent root object + */ + private Root root; + + /** + * the set of layout masters (provided by the root object) + */ + private LayoutMasterSet layoutMasterSet; + + // There doesn't seem to be anything in the spec requiring flows + // to be in the order given, only that they map to the regions + // defined in the page sequence, so all we need is this one hashmap + // the set of flows includes StaticContent flows also + + /** + * Map of flows to their flow name (flow-name, Flow) + */ + private HashMap flowMap; + + // according to communication from Paul Grosso (XSL-List, + // 001228, Number 406), confusion in spec section 6.4.5 about + // multiplicity of fo:flow in XSL 1.0 is cleared up - one (1) + // fo:flow per fo:page-sequence only. +// private boolean isFlowSet = false; + + // for structure handler + private boolean sequenceStarted = false; + + // + // state attributes used during layout + // + + private PageViewport currentPage; + + // page number and related formatting variables + private String ipnValue; + private int currentPageNumber = 0; + private int explicitFirstNumber = 0; // explicitly specified + private int firstPageNumber = 0; // actual + private PageNumberGenerator pageNumberGenerator; + + private int forcePageCount = 0; + private int pageCount = 0; + private boolean isForcing = false; + + /** + * specifies page numbering type (auto|auto-even|auto-odd|explicit) + */ + private int pageNumberType; + + /** + * used to determine whether to calculate auto, auto-even, auto-odd + */ + private boolean thisIsFirstPage; + + /** + * The currentSimplePageMaster is either the page master for the + * whole page sequence if master-reference refers to a simple-page-master, + * or the simple page master produced by the page sequence mster otherwise. + * The pageSequenceMaster is null if master-reference refers to a + * simple-page-master. + */ + private SimplePageMaster currentSimplePageMaster; + private PageSequenceMaster pageSequenceMaster; + + /** + * The main content flow for this page-sequence. + */ + private Flow mainFlow = null; + + /** + * The fo:title object for this page-sequence. + */ + private Title titleFO; + + /** + * Create a page sequence FO node. + * + * @param parent the parent FO node + */ + public PageSequence(FONode parent) { + super(parent); + } + + /** + * Handle the attributes for this xml element. + * For the page sequence this gets all the appropriate properties + * for dealing with the page sequence. + * + * @param attlist the attribute list + * @throws FOPException if there is an error with the properties + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + if (parent.getName().equals("fo:root")) { + this.root = (Root)parent; + // this.root.addPageSequence(this); + } else { + throw new FOPException("page-sequence must be child of root, not " + + parent.getName()); + } + + layoutMasterSet = root.getLayoutMasterSet(); + + // best time to run some checks on LayoutMasterSet + layoutMasterSet.checkRegionNames(); + + flowMap = new HashMap(); + + // we are now on the first page of the page sequence + thisIsFirstPage = true; + ipnValue = this.properties.get("initial-page-number").getString(); + + if (ipnValue.equals("auto")) { + pageNumberType = AUTO; + } else if (ipnValue.equals("auto-even")) { + pageNumberType = AUTO_EVEN; + } else if (ipnValue.equals("auto-odd")) { + pageNumberType = AUTO_ODD; + } else { + pageNumberType = EXPLICIT; + try { + int pageStart = new Integer(ipnValue).intValue(); + this.explicitFirstNumber = (pageStart > 0) ? pageStart - 1 : 0; + } catch (NumberFormatException nfe) { + throw new FOPException("\"" + ipnValue + + "\" is not a valid value for initial-page-number"); + } + } + + + String masterName = this.properties.get("master-reference").getString(); + this.currentSimplePageMaster = + this.layoutMasterSet.getSimplePageMaster(masterName); + if (this.currentSimplePageMaster == null) { + this.pageSequenceMaster = + this.layoutMasterSet.getPageSequenceMaster(masterName); + if (this.pageSequenceMaster == null) { + throw new FOPException("master-reference '" + masterName + + "' for fo:page-sequence matches no" + + " simple-page-master or page-sequence-master"); + } + } + + // get the 'format' properties + this.pageNumberGenerator = + new PageNumberGenerator(this.properties.get("format").getString(), + this.properties.get("grouping-separator").getCharacter(), + this.properties.get("grouping-size").getNumber().intValue(), + this.properties.get("letter-value").getEnum()); + this.pageNumberGenerator.enableLogging(getLogger()); + + this.forcePageCount = + this.properties.get("force-page-count").getEnum(); + + // this.properties.get("country"); + // this.properties.get("language"); + setupID(); + } + + + /** + * Add a flow or static content, mapped by its flow-name. + * The flow-name is used to associate the flow with a region on a page, + * based on the names given to the regions in the page-master used to + * generate that page. + */ +// private void addFlow(Flow flow) throws FOPException { +// if (flowMap.containsKey(flow.getFlowName())) { +// throw new FOPException("flow-names must be unique within an fo:page-sequence"); +// } +// if (!this.layoutMasterSet.regionNameExists(flow.getFlowName())) { +// getLogger().error("region-name '" +// + flow.getFlowName() +// + "' doesn't exist in the layout-master-set."); +// } +// flowMap.put(flow.getFlowName(), flow); +// //setIsFlowSet(true); +// } + + + /** + * Validate the child being added and initialize internal variables. + * XSL content model for page-sequence: + *

(title?,static-content*,flow)
+ * + * @param child The flow object child to be added to the PageSequence. + */ + public void addChild(FONode child) { + try { + String childName = child.getName(); + if (childName.equals("fo:title")) { + if (this.flowMap.size() > 0) { + getLogger().warn("fo:title should be first in page-sequence"); + } else { + this.titleFO = (Title)child; + } + } else if (childName.equals("fo:flow")) { + if (this.mainFlow != null) { + throw new FOPException("Only a single fo:flow permitted" + + " per fo:page-sequence"); + } else { + this.mainFlow = (Flow)child; + String flowName = this.mainFlow.getFlowName(); + if (flowMap.containsKey(flowName)) { + throw new FOPException("flow-name " + + flowName + + " is not unique within an fo:page-sequence"); + } + if (!this.layoutMasterSet.regionNameExists(flowName)) { + getLogger().error("region-name '" + + flowName + + "' doesn't exist in the layout-master-set."); + } + // Don't add main flow to the flow map +// addFlow(mainFlow); + if (!sequenceStarted) { + structHandler.startPageSequence(this, titleFO, layoutMasterSet); + sequenceStarted = true; + } + super.addChild(child); // For getChildren + } + } else if (childName.equals("fo:static-content")) { + if (this.mainFlow != null) { + throw new FOPException(childName + + " must precede fo:flow; ignoring"); + } + String flowName = ((StaticContent)child).getFlowName(); + if (flowMap.containsKey(flowName)) { + throw new FOPException("flow-name " + flowName + + " is not unique within an fo:page-sequence"); + } + if (!this.layoutMasterSet.regionNameExists(flowName)) { + getLogger().error("region-name '" + flowName + + "' doesn't exist in the layout-master-set."); + } + flowMap.put(flowName, child); +// addFlow((Flow)child); + if (!sequenceStarted) { + structHandler.startPageSequence(this, titleFO, layoutMasterSet); + sequenceStarted = true; + } + } else { + // Ignore it! + getLogger().warn("FO '" + childName + + "' not a legal page-sequence child."); + return; + } + } catch (FOPException fopex) { + getLogger().error("Error in PageSequence.addChild(): " + + fopex.getMessage(), fopex); + } + } + + /** + * Signal end of this xml element. + * This passes the end page sequence to the structure handler + * so it can act upon that. + */ + public void end() { + try { + this.structHandler.endPageSequence(this); + } catch (FOPException fopex) { + getLogger().error("Error in PageSequence.end(): " + + fopex.getMessage(), fopex); + } + } + + /** + * Runs the formatting of this page sequence into the given area tree + * + * @param areaTree the area tree to format this page sequence into + * @throws FOPException if there is an error formatting the contents + */ + public void format(AreaTree areaTree) throws FOPException { + // Make a new PageLayoutManager and a FlowLayoutManager + // Run the PLM in a thread + // Wait for them to finish. + + // If no main flow, nothing to layout! + if (this.mainFlow == null) { + return; + } + + // Initialize if already used? + // this.layoutMasterSet.resetPageMasters(); + if (pageSequenceMaster != null) { + pageSequenceMaster.reset(); + } + + int firstAvailPageNumber = 0; + initPageNumber(); + + // This will layout pages and add them to the area tree + PageLayoutManager pageLM = new PageLayoutManager(areaTree, this); + pageLM.setUserAgent(getUserAgent()); + pageLM.setFObj(this); + pageLM.setPageCounting(currentPageNumber, pageNumberGenerator); + + // For now, skip the threading and just call run directly. + pageLM.run(); + + // Thread layoutThread = new Thread(pageLM); +// layoutThread.start(); +// log.debug("Layout thread started"); + +// // wait on both managers +// try { +// layoutThread.join(); +// log.debug("Layout thread done"); +// } catch (InterruptedException ie) { +// log.error("PageSequence.format() interrupted waiting on layout"); +// } + this.currentPageNumber = pageLM.getPageCount(); + // Tell the root the last page number we created. + this.root.setRunningPageNumberCounter(this.currentPageNumber); + } + + /** + * Initialize the current page number for the start of the page sequence. + */ + private void initPageNumber() { + this.currentPageNumber = this.root.getRunningPageNumberCounter() + 1; + + if (this.pageNumberType == AUTO_ODD) { + // Next page but force odd. May force empty page creation! + // Whose master is used for this??? Assume no. + // Use force-page-count = auto + // on preceding page-sequence to make sure that there is no gap! + if (currentPageNumber % 2 == 0) { + this.currentPageNumber++; + } + } else if (pageNumberType == AUTO_EVEN) { + if (currentPageNumber % 2 == 1) { + this.currentPageNumber++; + } + } else if (pageNumberType == EXPLICIT) { + this.currentPageNumber = this.explicitFirstNumber; + } + this.firstPageNumber = this.currentPageNumber; + } + + /** + * Called by PageLayoutManager when it needs a new page on which to + * place content. The PageSequence manages the page number (odd/even), + * but the PLM tells it if the page is blank or is the last page. + * + * @param pageNumber the page number to create page for + * @param bIsBlank If true, use a master for a blank page. + * @param firstPage true if this is the first page + * @param bIsLast If true, use the master for the last page in the sequence. + * @return the page viewport created for the page number + * @throws FOPException if there is an error creating page + */ + public PageViewport createPage(int pageNumber, boolean bIsBlank, + boolean firstPage, boolean bIsLast) + throws FOPException { + if (this.pageSequenceMaster != null) { + this.currentSimplePageMaster = this.pageSequenceMaster + .getNextSimplePageMaster(((pageNumber % 2) == 1), + firstPage, + bIsBlank); + } + Region body = currentSimplePageMaster.getRegion(Region.BODY); + if (!this.mainFlow.getFlowName().equals(body.getRegionName())) { + throw new FOPException("Flow '" + this.mainFlow.getFlowName() + + "' does not map to the region-body in page-master '" + + currentSimplePageMaster.getMasterName() + "'"); + } + PageMaster pageMaster = this.currentSimplePageMaster.getPageMaster(); + PageViewport p = pageMaster.makePage(); + return p; + // The page will have a viewport/reference area pair defined + // for each region in the master. + // Set up the page itself +// SKIP ALL THIS FOR NOW!!! +// //this.root.setRunningPageNumberCounter(this.currentPageNumber); + +// this.pageCount++; // used for 'force-page-count' calculations + + // handle the 'force-page-count' + //forcePage(areaTree, firstAvailPageNumber); + } + + /** + * Creates a new page area for the given parameters + * @param areaTree the area tree the page should be contained in + * @param firstAvailPageNumber the page number for this page + * @param isFirstPage true when this is the first page in the sequence + * @param isEmptyPage true if this page will be empty + * (e.g. forced even or odd break) + * @return a Page layout object based on the page master selected + * from the params + * @todo modify the other methods to use even/odd flag and bIsLast + */ +// private PageViewport makePage(int firstAvailPageNumber, +// boolean isFirstPage, boolean bIsLast, +// boolean isEmptyPage) throws FOPException { +// // layout this page sequence + +// // while there is still stuff in the flow, ask the +// // layoutMasterSet for a new page + +// // page number is 0-indexed +// PageMaster pageMaster = getNextPageMaster(masterName, +// firstAvailPageNumber, +// isFirstPage, isEmptyPage); + +// // a legal alternative is to use the last sub-sequence +// // specification which should be handled in getNextSubsequence. +// // That's not done here. +// if (pageMaster == null) { +// throw new FOPException("page masters exhausted. Cannot recover."); +// } +// PageViewport p = pageMaster.makePage(); +// return p; +// } + + /** + * Returns the next SubSequenceSpecifier for the given page sequence master. + * The result is bassed on the current state of this page sequence. + */ +// private SubSequenceSpecifier getNextSubsequence(PageSequenceMaster master) { +// if (master.getSubSequenceSpecifierCount() +// > currentSubsequenceNumber + 1) { + +// currentSubsequence = +// master.getSubSequenceSpecifier(currentSubsequenceNumber + 1); +// currentSubsequenceNumber++; +// return currentSubsequence; +// } else { +// return null; +// } +// } + + /** + * Returns the next simple page master for the given sequence master, page number and + * other state information + */ +// private SimplePageMaster getNextSimplePageMaster(PageSequenceMaster sequenceMaster, +// int pageNumber, boolean thisIsFirstPage, +// boolean isEmptyPage) { +// // handle forcing +// if (isForcing) { +// String nextPageMaster = getNextPageMasterName(sequenceMaster, +// pageNumber, false, true); +// return this.layoutMasterSet.getSimplePageMaster(nextPageMaster); +// } +// String nextPageMaster = getNextPageMasterName(sequenceMaster, +// pageNumber, thisIsFirstPage, isEmptyPage); +// return this.layoutMasterSet.getSimplePageMaster(nextPageMaster); + +// } + + /** + * Get the next page master name. + * This gets the name of the next page master. If the sequence + * is exhausted then an error is indicated and the last page + * master name is used. + */ +// private String getNextPageMasterName(PageSequenceMaster sequenceMaster, +// int pageNumber, +// boolean thisIsFirstPage, +// boolean isEmptyPage) { + +// if (null == currentSubsequence) { +// currentSubsequence = getNextSubsequence(sequenceMaster); +// } + +// String nextPageMaster = +// currentSubsequence.getNextPageMaster(pageNumber, +// thisIsFirstPage, +// isEmptyPage); + + +// if (null == nextPageMaster +// || isFlowForMasterNameDone(currentPageMasterName)) { +// SubSequenceSpecifier nextSubsequence = +// getNextSubsequence(sequenceMaster); +// if (nextSubsequence == null) { +// getLogger().error("Page subsequences exhausted. Using previous subsequence."); +// thisIsFirstPage = +// true; // this becomes the first page in the new (old really) page master +// currentSubsequence.reset(); + +// // we leave currentSubsequence alone +// } +// else { +// currentSubsequence = nextSubsequence; +// } + +// nextPageMaster = +// currentSubsequence.getNextPageMaster(pageNumber, +// thisIsFirstPage, +// isEmptyPage); +// } +// currentPageMasterName = nextPageMaster; + +// return nextPageMaster; + +// } + +// private SimplePageMaster getCurrentSimplePageMaster() { +// return this.layoutMasterSet.getSimplePageMaster(currentPageMasterName); +// } + +// private String getCurrentPageMasterName() { +// return currentPageMasterName; +// } + + // refactored from LayoutMasterSet +// private PageMaster getNextPageMaster(String pageSequenceName, +// int pageNumber, +// boolean thisIsFirstPage, +// boolean isEmptyPage) throws FOPException { +// PageMaster pageMaster = null; + +// // see if there is a page master sequence for this master name +// PageSequenceMaster sequenceMaster = +// this.layoutMasterSet.getPageSequenceMaster(pageSequenceName); + +// if (sequenceMaster != null) { +// pageMaster = getNextSimplePageMaster(sequenceMaster, +// pageNumber, +// thisIsFirstPage, +// isEmptyPage).getPageMaster(); + +// } else { // otherwise see if there's a simple master by the given name +// SimplePageMaster simpleMaster = +// this.layoutMasterSet.getSimplePageMaster(pageSequenceName); +// if (simpleMaster == null) { +// throw new FOPException("'master-reference' for 'fo:page-sequence'" +// + "matches no 'simple-page-master'" +// + " or 'page-sequence-master'"); +// } +// currentPageMasterName = pageSequenceName; + +// pageMaster = simpleMaster.getNextPageMaster(); +// } +// return pageMaster; +// } + + +// /** +// * Returns true when there is more flow elements left to lay out. +// */ +// private boolean flowsAreIncomplete() { +// boolean isIncomplete = false; + +// for (Iterator e = flowMap.values().iterator(); e.hasNext(); ) { +// Flow flow = (Flow)e.next(); +// if (flow instanceof StaticContent) { +// continue; +// } + +// Status status = flow.getStatus(); +// isIncomplete |= status.isIncomplete(); +// } +// return isIncomplete; +// } + +// /** +// * Returns the flow that maps to the given region class for the current +// * page master. +// */ +// private Flow getCurrentFlow(String regionClass) { +// Region region = getCurrentSimplePageMaster().getRegion(regionClass); +// if (region != null) { +// Flow flow = (Flow)flowMap.get(region.getRegionName()); +// return flow; + +// } else { + +// getLogger().error("flow is null. regionClass = '" + regionClass +// + "' currentSPM = " +// + getCurrentSimplePageMaster()); + +// return null; +// } + +// } + +// private boolean isFlowForMasterNameDone(String masterName) { +// // parameter is master-name of PMR; we need to locate PM +// // referenced by this, and determine whether flow(s) are OK +// if (isForcing) +// return false; +// if (masterName != null) { + +// SimplePageMaster spm = +// this.layoutMasterSet.getSimplePageMaster(masterName); +// Region region = spm.getRegion(Region.BODY); + + +// Flow flow = (Flow)flowMap.get(region.getRegionName()); +// /*if ((null == flow) || flow.getStatus().isIncomplete()) +// return false; +// else +// return true;*/ +// } +// return false; +// } + +// public boolean isFlowSet() { +// return isFlowSet; +// } + +// public void setIsFlowSet(boolean isFlowSet) { +// this.isFlowSet = isFlowSet; +// } + + /** + * Get the "initial-page-number" value. + * + * @return the initial-page-number property value + */ + public String getIpnValue() { + return ipnValue; + } + + /** + * Get the current page number for this page sequence. + * + * @return the current page number + */ + public int getCurrentPageNumber() { + return currentPageNumber; + } + +// private void forcePage(AreaTree areaTree, int firstAvailPageNumber) { +// boolean makePage = false; +// if (this.forcePageCount == ForcePageCount.AUTO) { +// PageSequence nextSequence = +// this.root.getSucceedingPageSequence(this); +// if (nextSequence != null) { +// if (nextSequence.getIpnValue().equals("auto")) { +// // do nothing special +// } +// else if (nextSequence.getIpnValue().equals("auto-odd")) { +// if (firstAvailPageNumber % 2 == 0) { +// makePage = true; +// } +// } else if (nextSequence.getIpnValue().equals("auto-even")) { +// if (firstAvailPageNumber % 2 != 0) { +// makePage = true; +// } +// } else { +// int nextSequenceStartPageNumber = +// nextSequence.getCurrentPageNumber(); +// if ((nextSequenceStartPageNumber % 2 == 0) +// && (firstAvailPageNumber % 2 == 0)) { +// makePage = true; +// } else if ((nextSequenceStartPageNumber % 2 != 0) +// && (firstAvailPageNumber % 2 != 0)) { +// makePage = true; +// } +// } +// } +// } else if ((this.forcePageCount == ForcePageCount.EVEN) +// && (this.pageCount % 2 != 0)) { +// makePage = true; +// } else if ((this.forcePageCount == ForcePageCount.ODD) +// && (this.pageCount % 2 == 0)) { +// makePage = true; +// } else if ((this.forcePageCount == ForcePageCount.END_ON_EVEN) +// && (firstAvailPageNumber % 2 == 0)) { +// makePage = true; +// } else if ((this.forcePageCount == ForcePageCount.END_ON_ODD) +// && (firstAvailPageNumber % 2 != 0)) { +// makePage = true; +// } else if (this.forcePageCount == ForcePageCount.NO_FORCE) { +// // do nothing +// } + +// if (makePage) { +// try { +// this.isForcing = true; +// this.currentPageNumber++; +// firstAvailPageNumber = this.currentPageNumber; +// currentPage = makePage(areaTree, firstAvailPageNumber, false, +// true); +// String formattedPageNumber = +// pageNumberGenerator.makeFormattedPageNumber(this.currentPageNumber); +// currentPage.setFormattedNumber(formattedPageNumber); +// currentPage.setPageSequence(this); +// formatStaticContent(areaTree); +// log.debug("[forced-" + firstAvailPageNumber + "]"); +// areaTree.addPage(currentPage); +// this.root.setRunningPageNumberCounter(this.currentPageNumber); +// this.isForcing = false; +// } catch (FOPException fopex) { +// log.debug("'force-page-count' failure"); +// } +// } +// } + + /** + * Get the current simple page master + * that is active for the last page created. + * + * @return the current simple page master + */ + public SimplePageMaster getCurrentSimplePageMaster() { + return currentSimplePageMaster; + } + + /** + * Get the static content FO node from the flow map. + * This gets the static content flow for the given flow name. + * + * @param name the flow name to find + * @return the static content FO node + */ + public StaticContent getStaticContent(String name) { + return (StaticContent)flowMap.get(name); + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java new file mode 100644 index 000000000..86624ef1f --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java @@ -0,0 +1,200 @@ +/* + * $Id: PageSequenceMaster.java,v 1.13 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.util.List; + +// SAX +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.apps.FOPException; + +/** + * The page-sequence-master formatting object. + * This class handles a list of subsequence specifiers + * which are simple or complex references to page-masters. + */ +public class PageSequenceMaster extends FObj { + + private LayoutMasterSet layoutMasterSet; + private List subSequenceSpecifiers; + private SubSequenceSpecifier currentSubSequence; + private int currentSubSequenceNumber; + private String masterName; + + // The terminology may be confusing. A 'page-sequence-master' consists + // of a sequence of what the XSL spec refers to as + // 'sub-sequence-specifiers'. These are, in fact, simple or complex + // references to page-masters. So the methods use the former + // terminology ('sub-sequence-specifiers', or SSS), + // but the actual FO's are MasterReferences. + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public PageSequenceMaster(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + subSequenceSpecifiers = new java.util.ArrayList(); + + if (parent.getName().equals("fo:layout-master-set")) { + this.layoutMasterSet = (LayoutMasterSet)parent; + String pm = this.properties.get("master-name").getString(); + if (pm == null) { + getLogger().warn("page-sequence-master does not have " + + "a master-name and so is being ignored"); + } else { + this.layoutMasterSet.addPageSequenceMaster(pm, this); + } + } else { + throw new FOPException("fo:page-sequence-master must be child " + + "of fo:layout-master-set, not " + + parent.getName()); + } + } + + /** + * Adds a new suqsequence specifier to the page sequence master. + * @param pageMasterReference the subsequence to add + */ + protected void addSubsequenceSpecifier(SubSequenceSpecifier pageMasterReference) { + subSequenceSpecifiers.add(pageMasterReference); + } + + /** + * Returns the next subsequence specifier + * @return a subsequence specifier + */ + private SubSequenceSpecifier getNextSubSequence() { + currentSubSequenceNumber++; + if (currentSubSequenceNumber >= 0 + && currentSubSequenceNumber < subSequenceSpecifiers.size()) { + return (SubSequenceSpecifier)subSequenceSpecifiers + .get(currentSubSequenceNumber); + } + return null; + } + + /** + * Resets the subsequence specifiers subsystem. + */ + public void reset() { + currentSubSequenceNumber = -1; + currentSubSequence = null; + for (int i = 0; i < subSequenceSpecifiers.size(); i++) { + ((SubSequenceSpecifier)subSequenceSpecifiers.get(i)).reset(); + } + } + + /** + * Returns the next simple-page-master. + * @param isOddPage True if the next page number is odd + * @param isFirstPage True if the next page is the first + * @param isBlankPage True if the next page is blank + * @return the requested page master + * @throws FOPException if there's a problem determining the next page master + */ + public SimplePageMaster getNextSimplePageMaster(boolean isOddPage, + boolean isFirstPage, + boolean isBlankPage) + throws FOPException { + if (currentSubSequence == null) { + currentSubSequence = getNextSubSequence(); + if (currentSubSequence == null) { + throw new FOPException("no subsequences in page-sequence-master '" + + masterName + "'"); + } + } + String pageMasterName = currentSubSequence + .getNextPageMasterName(isOddPage, isFirstPage, isBlankPage); + boolean canRecover = true; + while (pageMasterName == null) { + SubSequenceSpecifier nextSubSequence = getNextSubSequence(); + if (nextSubSequence == null) { + if (!canRecover) { + throw new FOPException("subsequences exhausted in page-sequence-master '" + + masterName + + "', cannot recover"); + } + getLogger().warn("subsequences exhausted in page-sequence-master '" + + masterName + + "', use previous subsequence"); + currentSubSequence.reset(); + canRecover = false; + } else { + currentSubSequence = nextSubSequence; + } + pageMasterName = currentSubSequence + .getNextPageMasterName(isOddPage, isFirstPage, isBlankPage); + } + SimplePageMaster pageMaster = this.layoutMasterSet + .getSimplePageMaster(pageMasterName); + if (pageMaster == null) { + throw new FOPException("No simple-page-master matching '" + + pageMasterName + "' in page-sequence-master '" + + masterName + "'"); + } + return pageMaster; + } + +} + diff --git a/src/java/org/apache/fop/fo/pagination/Region.java b/src/java/org/apache/fop/fo/pagination/Region.java new file mode 100644 index 000000000..682595a47 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/Region.java @@ -0,0 +1,289 @@ +/* + * $Id: Region.java,v 1.18 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; + +// FOP +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FONode; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.CTM; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.layoutmgr.TraitSetter; + +// SAX +import org.xml.sax.Attributes; + +/** + * This is an abstract base class for pagination regions + */ +public abstract class Region extends FObj { + + private static final String PROP_REGION_NAME = "region-name"; + + /** Key for before regions */ + public static final String BEFORE = "before"; + /** Key for start regions */ + public static final String START = "start"; + /** Key for end regions */ + public static final String END = "end"; + /** Key for after regions */ + public static final String AFTER = "after"; + /** Key for body regions */ + public static final String BODY = "body"; + + private SimplePageMaster layoutMaster; + private String regionName; + + /** Holds the overflow attribute */ + protected int overflow; + /** Holds the writing mode */ + protected int wm; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + protected Region(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + // regions may have name, or default + if (null == this.properties.get(PROP_REGION_NAME)) { + setRegionName(getDefaultRegionName()); + } else if (this.properties.get(PROP_REGION_NAME).getString().equals("")) { + setRegionName(getDefaultRegionName()); + } else { + setRegionName(this.properties.get(PROP_REGION_NAME).getString()); + // check that name is OK. Not very pretty. + if (isReserved(getRegionName()) + && !getRegionName().equals(getDefaultRegionName())) { + throw new FOPException(PROP_REGION_NAME + " '" + regionName + + "' for " + this.name + + " not permitted."); + } + } + + if (parent instanceof SimplePageMaster) { + layoutMaster = (SimplePageMaster)parent; + } else { + throw new FOPException(this.name + " must be child " + + "of simple-page-master, not " + + parent.getName()); + } + this.wm = this.properties.get("writing-mode").getEnum(); + } + + /** + * Creates a RegionViewport Area object for this pagination Region. + * @param reldims relative dimensions + * @param pageCTM page coordinate transformation matrix + * @return the new region viewport + */ + public RegionViewport makeRegionViewport(FODimension reldims, CTM pageCTM) { + Rectangle2D relRegionRect = getViewportRectangle(reldims); + Rectangle2D absRegionRect = pageCTM.transform(relRegionRect); + // Get the region viewport rectangle in absolute coords by + // transforming it using the page CTM + RegionViewport rv = new RegionViewport(absRegionRect); + setRegionViewportTraits(rv); + return rv; + } + + /** + * Set the region viewport traits. + * The viewport has the border, background and + * clipping overflow traits. + * + * @param r the region viewport + */ + protected void setRegionViewportTraits(RegionViewport r) { + // Common Border, Padding, and Background Properties + BorderAndPadding bap = propMgr.getBorderAndPadding(); + BackgroundProps bProps = propMgr.getBackgroundProps(); + TraitSetter.addBorders(r, bap); + TraitSetter.addBackground(r, bProps); + + // this.properties.get("clip"); + // this.properties.get("display-align"); + this.overflow = this.properties.get("overflow").getEnum(); + } + + protected abstract Rectangle getViewportRectangle(FODimension pageRefRect); + + /** + * Create the region reference area for this region master. + * @param absRegVPRect The region viewport rectangle is "absolute" coordinates + * where x=distance from left, y=distance from bottom, width=right-left + * height=top-bottom + * @return a new region reference area + */ + public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) { + RegionReference r = new RegionReference(getRegionAreaClass()); + setRegionPosition(r, absRegVPRect); + return r; + } + + /** + * Set the region position inside the region viewport. + * This sets the trasnform that is used to place the contents of + * the region. + * + * @param r the region reference area + * @param absRegVPRect the rectangle to place the region contents + */ + protected void setRegionPosition(RegionReference r, Rectangle2D absRegVPRect) { + FODimension reldims = new FODimension(0, 0); + r.setCTM(propMgr.getCTMandRelDims(absRegVPRect, reldims)); + } + + /** + * Return the enumerated value designating this type of region in the + * Area tree. + * @return the region area class + */ + protected abstract int getRegionAreaClass(); + + /** + * Returns the default region name (xsl-region-before, xsl-region-start, + * etc.) + * @return the default region name + */ + protected abstract String getDefaultRegionName(); + + + /** + * Returns the region class name. + * @return the region class name + */ + public abstract String getRegionClass(); + + + /** + * Returns the name of this region. + * @return the region name + */ + public String getRegionName() { + return this.regionName; + } + + /** + * Sets the name of the region. + * @param name the name + */ + private void setRegionName(String name) { + this.regionName = name; + } + + /** + * Returns the page master associated with this region. + * @return a simple-page-master + */ + protected SimplePageMaster getPageMaster() { + return this.layoutMaster; + } + + /** + * Checks to see if a given region name is one of the reserved names + * + * @param name a region name to check + * @return true if the name parameter is a reserved region name + */ + protected boolean isReserved(String name) /*throws FOPException*/ { + return (name.equals("xsl-region-before") + || name.equals("xsl-region-start") + || name.equals("xsl-region-end") + || name.equals("xsl-region-after") + || name.equals("xsl-before-float-separator") + || name.equals("xsl-footnote-separator")); + } + + /** + * @see org.apache.fop.fo.FObj#generatesReferenceAreas() + */ + public boolean generatesReferenceAreas() { + return true; + } + + /** + * Returns a sibling region for this region. + * @param regionClass the class of the requested region + * @return the requested region + */ + protected Region getSiblingRegion(String regionClass) { + // Ask parent for region + return layoutMaster.getRegion(regionClass); + } + + /** + * Indicates if this region gets precedence. + * @return True if it gets precedence + */ + public boolean getPrecedence() { + return false; + } + + public int getExtent() { + return 0; + } +} diff --git a/src/java/org/apache/fop/fo/pagination/RegionAfter.java b/src/java/org/apache/fop/fo/pagination/RegionAfter.java new file mode 100644 index 000000000..55003c139 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionAfter.java @@ -0,0 +1,112 @@ +/* + * $Id: RegionAfter.java,v 1.17 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.area.RegionReference; + +/** + * The fo:region-after element. + */ +public class RegionAfter extends RegionBA { + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RegionAfter(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getViewportRectangle(FODimension) + */ + protected Rectangle getViewportRectangle (FODimension reldims) { + // Depends on extent, precedence ans writing mode + Rectangle vpRect; + if (this.wm == WritingMode.LR_TB || this.wm == WritingMode.RL_TB) { + vpRect = new Rectangle(0, reldims.bpd - getExtent(), reldims.ipd, getExtent()); + } else { + vpRect = new Rectangle(0, reldims.bpd - getExtent(), getExtent(), reldims.ipd); + } + if (getPrecedence() == false) { + adjustIPD(vpRect, this.wm); + } + return vpRect; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getDefaultRegionName() + */ + protected String getDefaultRegionName() { + return "xsl-region-after"; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionAreaClass() + */ + public int getRegionAreaClass() { + return RegionReference.AFTER; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionClass() + */ + public String getRegionClass() { + return Region.AFTER; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionBA.java b/src/java/org/apache/fop/fo/pagination/RegionBA.java new file mode 100644 index 000000000..6023be995 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionBA.java @@ -0,0 +1,120 @@ +/* + * $Id: RegionBA.java,v 1.6 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.Precedence; +import org.apache.fop.fo.properties.WritingMode; + +/** + * Abstract base class for fo:region-before and fo:region-after. + */ +public abstract class RegionBA extends RegionBASE { + + private boolean bPrecedence; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + protected RegionBA(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getPrecedence() + */ + public boolean getPrecedence() { + return bPrecedence; + } + + /** + * @see org.apache.fop.fo.FONode#end() + */ + public void end() { + super.end(); + bPrecedence = + (this.properties.get("precedence").getEnum() == Precedence.TRUE); + } + + /** + * Adjust the viewport reference rectangle for a region as a function + * of precedence. + * If precedence is false on a before or after region, its + * inline-progression-dimension is limited by the extent of the start + * and end regions if they are present. + * @param vpRect viewport rectangle + * @param wm writing mode + */ + protected void adjustIPD(Rectangle vpRect, int wm) { + int offset = 0; + Region start = getSiblingRegion(Region.START); + if (start != null) { + offset = start.getExtent(); + vpRect.translate(offset, 0); + } + Region end = getSiblingRegion(Region.END); + if (end != null) { + offset += end.getExtent(); + } + if (offset > 0) { + if (wm == WritingMode.LR_TB || wm == WritingMode.RL_TB) { + vpRect.width -= offset; + } else { + vpRect.height -= offset; + } + } + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionBASE.java b/src/java/org/apache/fop/fo/pagination/RegionBASE.java new file mode 100644 index 000000000..550f55e9e --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionBASE.java @@ -0,0 +1,86 @@ +/* + * $Id: RegionBASE.java,v 1.5 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// FOP +import org.apache.fop.fo.FONode; + +/** + * Base class for Before, After, Start and End regions (BASE). + */ +public abstract class RegionBASE extends Region { + + private int extent; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + protected RegionBASE(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#end() + */ + public void end() { + // The problem with this is that it might not be known yet.... + // Supposing extent is calculated in terms of percentage + this.extent = this.properties.get("extent").getLength().getValue(); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getExtent() + */ + public int getExtent() { + return this.extent; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionBefore.java b/src/java/org/apache/fop/fo/pagination/RegionBefore.java new file mode 100644 index 000000000..258cffb67 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionBefore.java @@ -0,0 +1,117 @@ +/* + * $Id: RegionBefore.java,v 1.18 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// FOP +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.fo.FONode; +import org.apache.fop.area.RegionReference; + +// Java +import java.awt.Rectangle; + +/** + * The fo:region-before element. + */ +public class RegionBefore extends RegionBA { + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RegionBefore(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getDefaultRegionName() + */ + protected String getDefaultRegionName() { + return "xsl-region-before"; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionClass() + */ + public String getRegionClass() { + return Region.BEFORE; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionAreaClass() + */ + public int getRegionAreaClass() { + return RegionReference.BEFORE; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getViewportRectangle(FODimension) + */ + protected Rectangle getViewportRectangle (FODimension reldims) { + // Depends on extent, precedence and writing mode + // This should return rectangle in writing-mode coordinates relative + // to the page-reference area rectangle + // This means the origin is (start, before) and the dimensions are (ipd,bpd) + // Before is always 0, start depends on extent + // ipd depends on precedence, bpd=extent + Rectangle vpRect; + if (this.wm == WritingMode.LR_TB || this.wm == WritingMode.RL_TB) { + vpRect = new Rectangle(0, 0, reldims.ipd, getExtent()); + } else { + vpRect = new Rectangle(0, 0, getExtent(), reldims.ipd); + } + if (getPrecedence() == false) { + adjustIPD(vpRect, this.wm); + } + return vpRect; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionBody.java b/src/java/org/apache/fop/fo/pagination/RegionBody.java new file mode 100644 index 000000000..e7b278c30 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionBody.java @@ -0,0 +1,173 @@ +/* + * $Id: RegionBody.java,v 1.23 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; +import java.awt.geom.Rectangle2D; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.properties.Overflow; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.BodyRegion; +import org.apache.fop.layout.MarginProps; + +/** + * The fo:region-body element. + */ +public class RegionBody extends Region { + + private ColorType backgroundColor; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RegionBody(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getViewportRectangle(FODimension) + */ + protected Rectangle getViewportRectangle (FODimension reldims) { + /* + * Use space-before and space-after which will use corresponding + * absolute margin properties if specified. For indents: + * try to get corresponding absolute margin property using the + * writing-mode on the page (not on the region-body!). If that's not + * set but indent is explicitly set, it will return that. + */ + MarginProps mProps = propMgr.getMarginProps(); + int start = getRelMargin(PropertyList.START, "start-indent"); + Rectangle vpRect; + if (this.wm == WritingMode.LR_TB || this.wm == WritingMode.RL_TB) { + vpRect = new Rectangle(start, mProps.spaceBefore, + reldims.ipd - start + - getRelMargin(PropertyList.END, "end-indent"), + reldims.bpd - mProps.spaceBefore - mProps.spaceAfter); + } else { + vpRect = new Rectangle(start, mProps.spaceBefore, + reldims.bpd - mProps.spaceBefore - mProps.spaceAfter, + reldims.ipd - start + - getRelMargin(PropertyList.END, "end-indent")); + } + return vpRect; + } + + /** + * Get the relative margin using parent's writing mode, not own + * writing mode. + */ + private int getRelMargin(int reldir, String sRelPropName) { + FObj parent = (FObj) getParent(); + String sPropName = "margin-" + + parent.properties.wmRelToAbs(reldir); + Property prop = properties.getExplicitBaseProp(sPropName); + if (prop == null) { + prop = properties.getExplicitBaseProp(sRelPropName); + } + return ((prop != null) ? prop.getLength().getValue() : 0); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getDefaultRegionName() + */ + protected String getDefaultRegionName() { + return "xsl-region-body"; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionClass() + */ + public String getRegionClass() { + return Region.BODY; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionAreaClass() + */ + public int getRegionAreaClass() { + return RegionReference.BODY; + } + + /** + * Override the inherited method. + * @see org.apache.fop.fo.pagination.Region#makeRegionReferenceArea(Rectangle2D) + */ + public RegionReference makeRegionReferenceArea(Rectangle2D absRegVPRect) { + // Should set some column stuff here I think, or put it elsewhere + BodyRegion body = new BodyRegion(); + setRegionPosition(body, absRegVPRect); + int columnCount = + this.properties.get("column-count").getNumber().intValue(); + if ((columnCount > 1) && (overflow == Overflow.SCROLL)) { + // recover by setting 'column-count' to 1. This is allowed but + // not required by the spec. + getLogger().error("Setting 'column-count' to 1 because " + + "'overflow' is set to 'scroll'"); + columnCount = 1; + } + body.setColumnCount(columnCount); + + int columnGap = + this.properties.get("column-gap").getLength().getValue(); + body.setColumnGap(columnGap); + return body; + } + +} diff --git a/src/java/org/apache/fop/fo/pagination/RegionEnd.java b/src/java/org/apache/fop/fo/pagination/RegionEnd.java new file mode 100644 index 000000000..d7039e59c --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionEnd.java @@ -0,0 +1,113 @@ +/* + * $Id: RegionEnd.java,v 1.11 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.area.RegionReference; + +/** + * The fo:region-end element. + */ +public class RegionEnd extends RegionSE { + + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RegionEnd(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getViewportRectangle(FODimension) + */ + protected Rectangle getViewportRectangle (FODimension reldims) { + // Depends on extent, precedence and writing mode + Rectangle vpRect; + if (this.wm == WritingMode.LR_TB || this.wm == WritingMode.RL_TB) { + vpRect = new Rectangle(reldims.ipd - getExtent(), 0, + getExtent(), reldims.bpd); + } else { + vpRect = new Rectangle(reldims.ipd - getExtent(), 0, + reldims.bpd, getExtent()); + } + adjustIPD(vpRect, this.wm); + return vpRect; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getDefaultRegionName() + */ + protected String getDefaultRegionName() { + return "xsl-region-end"; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionClass() + */ + public String getRegionClass() { + return Region.END; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionAreaClass() + */ + public int getRegionAreaClass() { + return RegionReference.END; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionSE.java b/src/java/org/apache/fop/fo/pagination/RegionSE.java new file mode 100644 index 000000000..b137a5d86 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionSE.java @@ -0,0 +1,102 @@ +/* + * $Id: RegionSE.java,v 1.5 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.WritingMode; + +/** + * Abstract base class for fo:region-start and fo:region-end. + */ +public abstract class RegionSE extends RegionBASE { + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + protected RegionSE(FONode parent) { + super(parent); + } + + /** + * Adjust the viewport reference rectangle for a region as a function + * of precedence. + * If before and after have precedence = true, the start and end + * regions only go to the limits of their extents, otherwise + * they extend in the BPD to the page reference rectangle + * diminish by extend of start and end if present. + * @param refRect reference rectangle + * @param wm writing mode + */ + protected void adjustIPD(Rectangle refRect, int wm) { + int offset = 0; + Region before = getSiblingRegion(Region.BEFORE); + if (before != null && before.getPrecedence()) { + offset = before.getExtent(); + refRect.translate(0, offset); + } + Region after = getSiblingRegion(Region.AFTER); + if (after != null && after.getPrecedence()) { + offset += after.getExtent(); + } + if (offset > 0) { + if (wm == WritingMode.LR_TB || wm == WritingMode.RL_TB) { + refRect.height -= offset; + } else { + refRect.width -= offset; + } + } + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RegionStart.java b/src/java/org/apache/fop/fo/pagination/RegionStart.java new file mode 100644 index 000000000..665e522c8 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RegionStart.java @@ -0,0 +1,112 @@ +/* + * $Id: RegionStart.java,v 1.12 2003/03/11 04:08:17 vmote Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.properties.WritingMode; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.area.RegionReference; + +/** + * The fo:region-start element. + */ +public class RegionStart extends RegionSE { + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RegionStart(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.pagination.Region#getViewportRectangle(FODimension) + */ + protected Rectangle getViewportRectangle (FODimension reldims) { + // Depends on extent, precedence and writing mode + // This is the rectangle relative to the page-reference area in + // writing-mode relative coordinates + Rectangle vpRect; + if (this.wm == WritingMode.LR_TB || this.wm == WritingMode.RL_TB) { + vpRect = new Rectangle(0, 0, getExtent(), reldims.bpd); + } else { + vpRect = new Rectangle(0, 0, reldims.bpd, getExtent()); + } + adjustIPD(vpRect, this.wm); + return vpRect; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getDefaultRegionName() + */ + protected String getDefaultRegionName() { + return "xsl-region-start"; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionClass() + */ + public String getRegionClass() { + return Region.START; + } + + /** + * @see org.apache.fop.fo.pagination.Region#getRegionAreaClass() + */ + public int getRegionAreaClass() { + return RegionReference.START; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java b/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java new file mode 100644 index 000000000..e976590b5 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternatives.java @@ -0,0 +1,168 @@ +/* + * $Id: RepeatablePageMasterAlternatives.java,v 1.12 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.util.ArrayList; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.apps.FOPException; + +/** + * A repeatable-page-master-alternatives formatting object. + * This contains a list of conditional-page-master-reference + * and the page master is found from the reference that + * matches the page number and emptyness. + */ +public class RepeatablePageMasterAlternatives extends FObj + implements SubSequenceSpecifier { + + private static final int INFINITE = -1; + + /** + * Max times this page master can be repeated. + * INFINITE is used for the unbounded case + */ + private int maximumRepeats; + private int numberConsumed = 0; + + private ArrayList conditionalPageMasterRefs; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RepeatablePageMasterAlternatives(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + conditionalPageMasterRefs = new ArrayList(); + + if (parent.getName().equals("fo:page-sequence-master")) { + PageSequenceMaster pageSequenceMaster = (PageSequenceMaster)parent; + pageSequenceMaster.addSubsequenceSpecifier(this); + } else { + throw new FOPException("fo:repeatable-page-master-alternatives " + + "must be child of fo:page-sequence-master, not " + + parent.getName()); + } + + String mr = getProperty("maximum-repeats").getString(); + if (mr.equals("no-limit")) { + this.maximumRepeats = INFINITE; + } else { + try { + this.maximumRepeats = Integer.parseInt(mr); + if (this.maximumRepeats < 0) { + getLogger().debug("negative maximum-repeats: " + + this.maximumRepeats); + this.maximumRepeats = 0; + } + } catch (NumberFormatException nfe) { + throw new FOPException("Invalid number for " + + "'maximum-repeats' property"); + } + } + } + + /** + * Get the next matching page master from the conditional + * page master references. + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier + */ + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isBlankPage) { + if (maximumRepeats != INFINITE) { + if (numberConsumed < maximumRepeats) { + numberConsumed++; + } else { + return null; + } + } + + for (int i = 0; i < conditionalPageMasterRefs.size(); i++) { + ConditionalPageMasterReference cpmr = + (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i); + if (cpmr.isValid(isOddPage, isFirstPage, isBlankPage)) { + return cpmr.getMasterName(); + } + } + return null; + } + + + /** + * Adds a new conditional page master reference. + * @param cpmr the new conditional reference + */ + public void addConditionalPageMasterReference(ConditionalPageMasterReference cpmr) { + this.conditionalPageMasterRefs.add(cpmr); + } + + /** + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier#reset() + */ + public void reset() { + this.numberConsumed = 0; + } + +} diff --git a/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java b/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java new file mode 100644 index 000000000..3dcc76728 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/RepeatablePageMasterReference.java @@ -0,0 +1,129 @@ +/* + * $Id: RepeatablePageMasterReference.java,v 1.8 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.apps.FOPException; + +/** + * A repeatable-page-master-reference formatting object. + * This handles a reference with a specified number of repeating + * instances of the referenced page master (may have no limit). + */ +public class RepeatablePageMasterReference extends PageMasterReference + implements SubSequenceSpecifier { + + private static final int INFINITE = -1; + + private PageSequenceMaster pageSequenceMaster; + + private int maximumRepeats; + private int numberConsumed = 0; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public RepeatablePageMasterReference(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + String mr = getProperty("maximum-repeats").getString(); + if (mr.equals("no-limit")) { + this.maximumRepeats = INFINITE; + } else { + try { + this.maximumRepeats = Integer.parseInt(mr); + if (this.maximumRepeats < 0) { + getLogger().debug("negative maximum-repeats: " + + this.maximumRepeats); + this.maximumRepeats = 0; + } + } catch (NumberFormatException nfe) { + throw new FOPException("Invalid number for " + + "'maximum-repeats' property"); + } + } + } + + /** + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier + */ + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { + if (maximumRepeats != INFINITE) { + if (numberConsumed < maximumRepeats) { + numberConsumed++; + } else { + return null; + } + } + return getMasterName(); + } + + /** + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier#reset() + */ + public void reset() { + this.numberConsumed = 0; + } + +} diff --git a/src/java/org/apache/fop/fo/pagination/Root.java b/src/java/org/apache/fop/fo/pagination/Root.java new file mode 100644 index 000000000..e5f2a79be --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/Root.java @@ -0,0 +1,141 @@ +/* + * $Id: Root.java,v 1.24 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// FOP +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FONode; + +// Java +import java.util.List; + +/** + * The fo:root formatting object. Contains page masters, page-sequences. + */ +public class Root extends FObj { + private LayoutMasterSet layoutMasterSet; + private List pageSequences; + + /** + * Keeps count of page number from over PageSequence instances + */ + private int runningPageNumberCounter = 0; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public Root(FONode parent) { + super(parent); + // this.properties.get("media-usage"); + pageSequences = new java.util.ArrayList(); + if (parent != null) { + //throw new FOPException("root must be root element"); + } + } + + /** + * Returns the number of pages generated (over all PageSequence instances). + * @return the number of pages + */ + protected int getRunningPageNumberCounter() { + return this.runningPageNumberCounter; + } + + /** + * Sets the overall page number counter. + * @param count the new page count + */ + protected void setRunningPageNumberCounter(int count) { + this.runningPageNumberCounter = count; + } + + /** + * Returns the number of PageSequence instances. + * @return the number of PageSequence instances + */ + public int getPageSequenceCount() { + return pageSequences.size(); + } + + /** + * Some properties, such as 'force-page-count', require a + * page-sequence to know about some properties of the next. + * @param current the current PageSequence + * @return succeeding PageSequence; null if none + */ + public PageSequence getSucceedingPageSequence(PageSequence current) { + int currentIndex = pageSequences.indexOf(current); + if (currentIndex == -1) { + return null; + } + if (currentIndex < (pageSequences.size() - 1)) { + return (PageSequence)pageSequences.get(currentIndex + 1); + } else { + return null; + } + } + + /** + * Returns the associated LayoutMasterSet. + * @return the LayoutMasterSet instance + */ + public LayoutMasterSet getLayoutMasterSet() { + return this.layoutMasterSet; + } + + /** + * Sets the associated LayoutMasterSet. + * @param layoutMasterSet the LayoutMasterSet to use + */ + public void setLayoutMasterSet(LayoutMasterSet layoutMasterSet) { + this.layoutMasterSet = layoutMasterSet; + } +} diff --git a/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java b/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java new file mode 100644 index 000000000..3353fe1f8 --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/SimplePageMaster.java @@ -0,0 +1,273 @@ +/* + * $Id: SimplePageMaster.java,v 1.30 2003/03/06 13:42:41 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +// Java +import java.awt.Rectangle; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +// XML +import org.xml.sax.Attributes; + +// FOP +import org.apache.fop.area.CTM; +import org.apache.fop.datatypes.FODimension; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FObj; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Page; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.PageMaster; +import org.apache.fop.apps.FOPException; + +/** + * A simple-page-master formatting object. + * This creates a simple page from the specified regions + * and attributes. + */ +public class SimplePageMaster extends FObj { + /** + * Page regions (regionClass, Region) + */ + private Map regions; + + private PageMaster pageMaster; + private String masterName; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public SimplePageMaster(FONode parent) { + super(parent); + } + + /** + * @see org.apache.fop.fo.FONode#handleAttrs(Attributes) + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + + if (parent.getName().equals("fo:layout-master-set")) { + LayoutMasterSet layoutMasterSet = (LayoutMasterSet)parent; + masterName = this.properties.get("master-name").getString(); + if (masterName == null) { + getLogger().warn("simple-page-master does not have " + + "a master-name and so is being ignored"); + } else { + layoutMasterSet.addSimplePageMaster(this); + } + } else { + throw new FOPException("fo:simple-page-master must be child " + + "of fo:layout-master-set, not " + + parent.getName()); + } + //Well, there are only 5 regions so we can save a bit of memory here + regions = new HashMap(5); + } + + /** + * At the end of this element read all the information and create + * the page master. + */ + protected void end() { + int pageWidth = + this.properties.get("page-width").getLength().getValue(); + int pageHeight = + this.properties.get("page-height").getLength().getValue(); + // this.properties.get("reference-orientation"); + // this.properties.get("writing-mode"); + + // Get absolute margin properties (top, left, bottom, right) + MarginProps mProps = propMgr.getMarginProps(); + + /* Create the page reference area rectangle (0,0 is at top left + * of the "page media" and y increases + * when moving towards the bottom of the page. + * The media rectangle itself is (0,0,pageWidth,pageHeight). + */ + Rectangle pageRefRect = + new Rectangle(mProps.marginLeft, mProps.marginTop, + pageWidth - mProps.marginLeft - mProps.marginRight, + pageHeight - mProps.marginTop - mProps.marginBottom); + + // ??? KL shouldn't this take the viewport too??? + Page page = new Page(); // page reference area + + // Set up the CTM on the page reference area based on writing-mode + // and reference-orientation + FODimension reldims = new FODimension(0, 0); + CTM pageCTM = propMgr.getCTMandRelDims(pageRefRect, reldims); + + // Create a RegionViewport/ reference area pair for each page region + + boolean bHasBody = false; + + for (Iterator regenum = regions.values().iterator(); + regenum.hasNext();) { + Region r = (Region)regenum.next(); + RegionViewport rvp = r.makeRegionViewport(reldims, pageCTM); + rvp.setRegion(r.makeRegionReferenceArea(rvp.getViewArea())); + page.setRegion(r.getRegionAreaClass(), rvp); + if (r.getRegionAreaClass() == RegionReference.BODY) { + bHasBody = true; + } + } + + if (!bHasBody) { + getLogger().error("simple-page-master has no region-body"); + } + + this.pageMaster = new PageMaster(new PageViewport(page, + new Rectangle(0, 0, pageWidth, pageHeight))); + + // regions = null; // PageSequence access SimplePageMaster.... + children = null; + properties = null; + } + + /** + * @see org.apache.fop.fo.FObj#generatesReferenceAreas() + */ + public boolean generatesReferenceAreas() { + return true; + } + + /** + * Returns the page master. + * @return the page master + */ + public PageMaster getPageMaster() { + return this.pageMaster; + } + + /** + * Returns the next page master. For simple-page-master this is always the + * same as the previous. + * @return the page master + */ + public PageMaster getNextPageMaster() { + return this.pageMaster; + } + + /** + * Returns the name of the simple-page-master. + * @return the page master name + */ + public String getMasterName() { + return masterName; + } + + /** + * @see org.apache.fop.fo.FONode#addChild(FONode) + */ + protected void addChild(FONode child) { + if (child instanceof Region) { + addRegion((Region)child); + } else { + getLogger().error("SimplePageMaster cannot have child of type " + + child.getName()); + } + } + + /** + * Adds a region to this simple-page-master. + * @param region region to add + */ + protected void addRegion(Region region) { + String key = region.getRegionClass(); + if (regions.containsKey(key)) { + getLogger().error("Only one region of class " + key + + " allowed within a simple-page-master. The duplicate" + + " region (" + region.getName() + ") is ignored."); + } else { + regions.put(key, region); + } + } + + /** + * Returns the region for a given region class. + * @param regionClass region class to lookup + * @return the region, null if it doesn't exist + */ + public Region getRegion(String regionClass) { + return (Region)regions.get(regionClass); + } + + /** + * Returns a Map of regions associated with this simple-page-master + * @return the regions + */ + protected Map getRegions() { + return regions; + } + + /** + * Indicates if a region with a given name exists in this + * simple-page-master. + * @param regionName name of the region to lookup + * @return True if a region with this name exists + */ + protected boolean regionNameExists(String regionName) { + for (Iterator regenum = regions.values().iterator(); + regenum.hasNext();) { + Region r = (Region)regenum.next(); + if (r.getRegionName().equals(regionName)) { + return true; + } + } + return false; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java b/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java new file mode 100644 index 000000000..2f10a102f --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/SinglePageMasterReference.java @@ -0,0 +1,97 @@ +/* + * $Id: SinglePageMasterReference.java,v 1.9 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +import org.apache.fop.fo.FONode; + +/** + * A single-page-master-reference formatting object. + * This is a reference for a single page. It returns the + * master name only once until reset. + */ +public class SinglePageMasterReference extends PageMasterReference + implements SubSequenceSpecifier { + + private static final int FIRST = 0; + private static final int DONE = 1; + + private int state; + + /** + * @see org.apache.fop.fo.FONode#FONode(FONode) + */ + public SinglePageMasterReference(FONode parent) { + super(parent); + this.state = FIRST; + } + + /** + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier + */ + public String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isEmptyPage) { + if (this.state == FIRST) { + this.state = DONE; + return getMasterName(); + } else { + return null; + } + } + + /** + * @see org.apache.fop.fo.pagination.SubSequenceSpecifier#reset() + */ + public void reset() { + this.state = FIRST; + } +} + diff --git a/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java b/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java new file mode 100644 index 000000000..98f2ef4dd --- /dev/null +++ b/src/java/org/apache/fop/fo/pagination/SubSequenceSpecifier.java @@ -0,0 +1,81 @@ +/* + * $Id: SubSequenceSpecifier.java,v 1.5 2003/03/06 13:42:42 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fo.pagination; + +import org.apache.fop.apps.FOPException; + +/** + * Classes that implement this interface can be added to a PageSequenceMaster, + * and are capable of looking up an appropriate PageMaster. + */ +public interface SubSequenceSpecifier { + + /** + * Returns the name of the next page master. + * @param isOddPage True if the next page number is odd + * @param isFirstPage True if the next page is the first + * @param isBlankPage True if the next page is blank + * @return the page master name + * @throws FOPException if there's a problem determining the next page master + */ + String getNextPageMasterName(boolean isOddPage, + boolean isFirstPage, + boolean isBlankPage) + throws FOPException; + + /** + * Called before a new page sequence is rendered so subsequences can reset + * any state they keep during the formatting process. + */ + void reset(); + +} + diff --git a/src/java/org/apache/fop/fonts/BFEntry.java b/src/java/org/apache/fop/fonts/BFEntry.java new file mode 100644 index 000000000..28ed8955c --- /dev/null +++ b/src/java/org/apache/fop/fonts/BFEntry.java @@ -0,0 +1,98 @@ +/* + * $Id: BFEntry.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +/** + * This is just a holder class for bfentries. + */ +public class BFEntry { + + private int unicodeStart; + private int unicodeEnd; + private int glyphStartIndex; + + /** + * Main constructor. + * @param unicodeStart Unicode start index + * @param unicodeEnd Unicode end index + * @param glyphStartIndex glyph start index + */ + public BFEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) { + this.unicodeStart = unicodeStart; + this.unicodeEnd = unicodeEnd; + this.glyphStartIndex = glyphStartIndex; + } + + /** + * Returns the unicodeStart. + * @return the Unicode start index + */ + public int getUnicodeStart() { + return unicodeStart; + } + + /** + * Returns the unicodeEnd. + * @return the Unicode end index + */ + public int getUnicodeEnd() { + return unicodeEnd; + } + + /** + * Returns the glyphStartIndex. + * @return the glyph start index + */ + public int getGlyphStartIndex() { + return glyphStartIndex; + } + +} diff --git a/src/java/org/apache/fop/fonts/CIDFont.java b/src/java/org/apache/fop/fonts/CIDFont.java new file mode 100644 index 000000000..2697cda8e --- /dev/null +++ b/src/java/org/apache/fop/fonts/CIDFont.java @@ -0,0 +1,107 @@ +/* + * $Id: CIDFont.java,v 1.3 2003/03/11 04:06:43 vmote Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +/** + * Abstract base class for CID fonts. + */ +public abstract class CIDFont extends CustomFont { + + // ---- Required ---- + /** + * Returns the name of the base font. + * @return the name of the base font + */ + public abstract String getCidBaseFont(); + + /** + * Returns the type of the CID font. + * @return the type of the CID font + */ + public abstract CIDFontType getCIDType(); + + /** + * Returns the name of the issuer of the font. + * @return a String identifying an issuer of character collections - + * for example, Adobe + */ + public abstract String getRegistry(); + + /** + * Returns a font name for use within a registry. + * @return a String that uniquely names a character collection issued by + * a specific registry - for example, Japan1. + */ + public abstract String getOrdering(); + + /** + * Returns the supplement number of the character collection. + * @return the supplement number + */ + public abstract int getSupplement(); + + + // ---- Optional ---- + /** + * Returns the default width for this font. + * @return the default width + */ + public int getDefaultWidth() { + return 0; + } + + /** + * @see org.apache.fop.fonts.Font#isMultiByte() + */ + public boolean isMultiByte() { + return true; + } +} diff --git a/src/java/org/apache/fop/fonts/CIDFontType.java b/src/java/org/apache/fop/fonts/CIDFontType.java new file mode 100644 index 000000000..7ea2c6e75 --- /dev/null +++ b/src/java/org/apache/fop/fonts/CIDFontType.java @@ -0,0 +1,110 @@ +/* + * $Id: CIDFontType.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +import org.apache.avalon.framework.ValuedEnum; + +/** + * This class enumerates all supported CID font types. + */ +public class CIDFontType extends ValuedEnum { + + /** + * CID Font Type 0 + */ + public static final CIDFontType CIDTYPE0 = new CIDFontType("CIDFontType0", 0); + + /** + * CID Font Type 2 + */ + public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 1); + + + /** + * @see org.apache.avalon.framework.Enum#Enum(String) + */ + protected CIDFontType(String name, int value) { + super(name, value); + } + + + /** + * Returns the CIDFontType by name. + * @param name Name of the CID font type to look up + * @return FontType the CID font type + */ + public static CIDFontType byName(String name) { + if (name.equalsIgnoreCase(CIDFontType.CIDTYPE0.getName())) { + return CIDFontType.CIDTYPE0; + } else if (name.equalsIgnoreCase(CIDFontType.CIDTYPE2.getName())) { + return CIDFontType.CIDTYPE2; + } else { + throw new IllegalArgumentException("Invalid CID font type: " + name); + } + } + + + /** + * Returns the CID FontType by value. + * @param value Value of the CID font type to look up + * @return FontType the CID font type + */ + public static CIDFontType byValue(int value) { + if (value == CIDFontType.CIDTYPE0.getValue()) { + return CIDFontType.CIDTYPE0; + } else if (value == CIDFontType.CIDTYPE2.getValue()) { + return CIDFontType.CIDTYPE2; + } else { + throw new IllegalArgumentException("Invalid CID font type: " + value); + } + } + +} diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java new file mode 100644 index 000000000..f8fb45fd3 --- /dev/null +++ b/src/java/org/apache/fop/fonts/CustomFont.java @@ -0,0 +1,370 @@ +/* + * $Id: CustomFont.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +import java.util.Map; + + +/** + * Abstract base class for custom fonts loaded from files, for example. + */ +public abstract class CustomFont extends Font + implements FontDescriptor, MutableFont { + + private String fontName = null; + private String embedFileName = null; + private String embedResourceName = null; + + private int capHeight = 0; + private int xHeight = 0; + private int ascender = 0; + private int descender = 0; + private int[] fontBBox = {0, 0, 0, 0}; + private int flags = 4; + private int stemV = 0; + private int italicAngle = 0; + private int missingWidth = 0; + private FontType fontType = FontType.TYPE1; + private int firstChar = 0; + private int lastChar = 255; + + private Map kerning = new java.util.HashMap(); + + + private boolean useKerning = true; + + + /** + * @see org.apache.fop.fonts.FontMetrics#getFontName() + */ + public String getFontName() { + return fontName; + } + + /** + * Returns an URI representing an embeddable font file. The URI will often + * be a filename or an URL. + * @return URI to an embeddable font file or null if not available. + */ + public String getEmbedFileName() { + return embedFileName; + } + + /** + * Returns the lookup name to an embeddable font file available as a + * resource. + * @todo Remove this method, this should be done using a resource: URI. + * @return the lookup name + */ + public String getEmbedResourceName() { + return embedResourceName; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getAscender() + */ + public int getAscender() { + return ascender; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getDescender() + */ + public int getDescender() { + return descender; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getCapHeight() + */ + public int getCapHeight() { + return capHeight; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getAscender(int) + */ + public int getAscender(int size) { + return size * ascender; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getDescender(int) + */ + public int getDescender(int size) { + return size * descender; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int) + */ + public int getCapHeight(int size) { + return size * capHeight; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getXHeight(int) + */ + public int getXHeight(int size) { + return size * xHeight; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFontBBox() + */ + public int[] getFontBBox() { + return fontBBox; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFlags() + */ + public int getFlags() { + return flags; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getStemV() + */ + public int getStemV() { + return stemV; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getItalicAngle() + */ + public int getItalicAngle() { + return italicAngle; + } + + /** + * Returns the width to be used when no width is available. + * @return a character width + */ + public int getMissingWidth() { + return missingWidth; + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFontType() + */ + public FontType getFontType() { + return fontType; + } + + /** + * Returns the index of the first character defined in this font. + * @return the index of the first character + */ + public int getFirstChar() { + return 0; + // return firstChar; + /**@todo Why is this hardcoded??? This code was in SingleByteFont.java */ + } + + /** + * Returns the index of the last character defined in this font. + * @return the index of the last character + */ + public int getLastChar() { + return lastChar; + } + + /** + * Used to determine if kerning is enabled. + * @return True if kerning is enabled. + */ + public boolean isKerningEnabled() { + return useKerning; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo() + */ + public final boolean hasKerningInfo() { + return (isKerningEnabled() & kerning.isEmpty()); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getKerningInfo() + */ + public final Map getKerningInfo() { + if (isKerningEnabled()) { + return kerning; + } else { + return java.util.Collections.EMPTY_MAP; + } + } + + + /* ---- MutableFont interface ---- */ + + /** + * @see org.apache.fop.fonts.MutableFont#setFontName(String) + */ + public void setFontName(String name) { + this.fontName = name; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setEmbedFileName(String) + */ + public void setEmbedFileName(String path) { + this.embedFileName = path; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setEmbedResourceName(String) + */ + public void setEmbedResourceName(String name) { + this.embedResourceName = name; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setCapHeight(int) + */ + public void setCapHeight(int capHeight) { + this.capHeight = capHeight; + } + + /** + * Returns the XHeight value of the font. + * @param xHeight the XHeight value + */ + public void setXHeight(int xHeight) { + this.xHeight = xHeight; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setAscender(int) + */ + public void setAscender(int ascender) { + this.ascender = ascender; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setDescender(int) + */ + public void setDescender(int descender) { + this.descender = descender; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setFontBBox(int[]) + */ + public void setFontBBox(int[] bbox) { + this.fontBBox = bbox; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setFlags(int) + */ + public void setFlags(int flags) { + this.flags = flags; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setStemV(int) + */ + public void setStemV(int stemV) { + this.stemV = stemV; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setItalicAngle(int) + */ + public void setItalicAngle(int italicAngle) { + this.italicAngle = italicAngle; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setMissingWidth(int) + */ + public void setMissingWidth(int width) { + this.missingWidth = width; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setFontType(FontType) + */ + public void setFontType(FontType fontType) { + this.fontType = fontType; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setFirstChar(int) + */ + public void setFirstChar(int index) { + this.firstChar = index; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setLastChar(int) + */ + public void setLastChar(int index) { + this.lastChar = index; + } + + /** + * @see org.apache.fop.fonts.MutableFont#setKerningEnabled(boolean) + */ + public void setKerningEnabled(boolean enabled) { + this.useKerning = enabled; + } + + /** + * @see org.apache.fop.fonts.MutableFont#putKerningEntry(Integer, Map) + */ + public void putKerningEntry(Integer key, Map value) { + this.kerning.put(key, value); + } + +} diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java new file mode 100644 index 000000000..3d0b2ed0f --- /dev/null +++ b/src/java/org/apache/fop/fonts/Font.java @@ -0,0 +1,83 @@ +/* + * $Id: Font.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +// FOP + + +/** + * Base class for PDF font classes + */ +public abstract class Font implements FontMetrics { + + /** + * Get the encoding of the font. + * @return the encoding + */ + public abstract String getEncoding(); + + /** + * Map a Unicode character to a code point in the font. + * @param c character to map + * @return the mapped character + */ + public abstract char mapChar(char c); + + /** + * Determines whether the font is a multibyte font. + * @return True if it is multibyte + */ + public boolean isMultiByte() { + return false; + } + +} + diff --git a/src/java/org/apache/fop/fonts/FontDescriptor.java b/src/java/org/apache/fop/fonts/FontDescriptor.java new file mode 100644 index 000000000..6bee29648 --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontDescriptor.java @@ -0,0 +1,116 @@ +/* + * $Id: FontDescriptor.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +/** + * This interface enhances the font metrics interface with access methods to + * value needed to register fonts in various target formats like PDF or + * PostScript. + */ +public interface FontDescriptor extends FontMetrics { + + /** + * Returns the ascender value of the font. (Ascent in pdf spec) + * @return the ascender + */ + int getAscender(); + + + /** + * Returns the capital height of the font. + * @return the capiptal height + */ + int getCapHeight(); + + + /** + * Returns the descender value of the font. (Descent in pdf spec) + * @return the descender value + */ + int getDescender(); + + + /** + * Returns the flags for the font. (See pdf spec) + * @return the flags + */ + int getFlags(); + + + /** + * Returns the font's bounding box. + * @return the bounding box + */ + int[] getFontBBox(); + + + /** + * Returns the italic angle for the font. + * @return the italic angle + */ + int getItalicAngle(); + + + /** + * Returns the vertical stem width for the font. + * @return the vertical stem width + */ + int getStemV(); + + + /** + * Indicates if this font may be embedded. + * @return True, if embedding is possible/permitted + */ + boolean isEmbeddable(); + + +} diff --git a/src/java/org/apache/fop/fonts/FontMetrics.java b/src/java/org/apache/fop/fonts/FontMetrics.java new file mode 100644 index 000000000..7fa3d2135 --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontMetrics.java @@ -0,0 +1,138 @@ +/* + * $Id: FontMetrics.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +import java.util.Map; + + +/** + * Main interface for access to font metrics. + */ +public interface FontMetrics { + + /** + * Returns the font name. + * @return the font name + */ + String getFontName(); + + + /** + * Returns the type of the font. + * @return the font type + */ + FontType getFontType(); + + + /** + * Returns the ascent of the font described by this + * FontMetrics object. + * @param size font size + * @return ascent in milliponts + */ + int getAscender(int size); + + /** + * Returns the size of a capital letter measured from the font's baseline. + * @param size font size + * @return height of capital characters + */ + int getCapHeight(int size); + + + /** + * Returns the descent of the font described by this + * FontMetrics object. + * @param size font size + * @return descent in milliponts + */ + int getDescender(int size); + + + /** + * Determines the typical font height of this + * FontMetrics object + * @param size font size + * @return font height in millipoints + */ + int getXHeight(int size); + + /** + * Return the width (in 1/1000ths of point size) of the character at + * code point i. + * @param i code point index + * @param size font size + * @return the width of the character + */ + int getWidth(int i, int size); + + /** + * Return the array of widths. + *

+ * This is used to get an array for inserting in an output format. + * It should not be used for lookup. + * @return an array of widths + */ + int[] getWidths(); + + /** + * Indicates if the font has kering information. + * @return True, if kerning is available. + */ + boolean hasKerningInfo(); + + /** + * Returns the kerning map for the font. + * @return the kerning map + */ + Map getKerningInfo(); + +} diff --git a/src/java/org/apache/fop/fonts/FontType.java b/src/java/org/apache/fop/fonts/FontType.java new file mode 100644 index 000000000..99334cf08 --- /dev/null +++ b/src/java/org/apache/fop/fonts/FontType.java @@ -0,0 +1,141 @@ +/* + * $Id: FontType.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +import org.apache.avalon.framework.ValuedEnum; + +/** + * This class enumerates all supported font types. + */ +public class FontType extends ValuedEnum { + + /** + * Collective identifier for "other" font types + */ + public static final FontType OTHER = new FontType("Other", 0); + /** + * Adobe Type 0 fonts + */ + public static final FontType TYPE0 = new FontType("Type0", 1); + /** + * Adobe Type 1 fonts + */ + public static final FontType TYPE1 = new FontType("Type1", 2); + /** + * Adobe Multiple Master Type 1 fonts + */ + public static final FontType MMTYPE1 = new FontType("MMType1", 3); + /** + * Adobe Type 3 fonts ("user-defined" fonts) + */ + public static final FontType TYPE3 = new FontType("Type3", 4); + /** + * TrueType fonts + */ + public static final FontType TRUETYPE = new FontType("TrueType", 5); + + + /** + * @see org.apache.avalon.framework.Enum#Enum(String) + */ + protected FontType(String name, int value) { + super(name, value); + } + + + /** + * Returns the FontType by name. + * @param name Name of the font type to look up + * @return the font type + */ + public static FontType byName(String name) { + if (name.equalsIgnoreCase(FontType.OTHER.getName())) { + return FontType.OTHER; + } else if (name.equalsIgnoreCase(FontType.TYPE0.getName())) { + return FontType.TYPE0; + } else if (name.equalsIgnoreCase(FontType.TYPE1.getName())) { + return FontType.TYPE1; + } else if (name.equalsIgnoreCase(FontType.MMTYPE1.getName())) { + return FontType.MMTYPE1; + } else if (name.equalsIgnoreCase(FontType.TYPE3.getName())) { + return FontType.TYPE3; + } else if (name.equalsIgnoreCase(FontType.TRUETYPE.getName())) { + return FontType.TRUETYPE; + } else { + throw new IllegalArgumentException("Invalid font type: " + name); + } + } + + + /** + * Returns the FontType by value. + * @param value Value of the font type to look up + * @return the font type + */ + public static FontType byValue(int value) { + if (value == FontType.OTHER.getValue()) { + return FontType.OTHER; + } else if (value == FontType.TYPE0.getValue()) { + return FontType.TYPE0; + } else if (value == FontType.TYPE1.getValue()) { + return FontType.TYPE1; + } else if (value == FontType.MMTYPE1.getValue()) { + return FontType.MMTYPE1; + } else if (value == FontType.TYPE3.getValue()) { + return FontType.TYPE3; + } else if (value == FontType.TRUETYPE.getValue()) { + return FontType.TRUETYPE; + } else { + throw new IllegalArgumentException("Invalid font type: " + value); + } + } + +} diff --git a/src/java/org/apache/fop/fonts/Glyphs.java b/src/java/org/apache/fop/fonts/Glyphs.java new file mode 100644 index 000000000..96d35242b --- /dev/null +++ b/src/java/org/apache/fop/fonts/Glyphs.java @@ -0,0 +1,1331 @@ +/* + * $Id: Glyphs.java,v 1.10 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +/** + * This class provides a number of constants for glyph management. + */ +public class Glyphs { + + /** + * Glyph name for the "notdef" glyph + */ + public static final String NOTDEF = ".notdef"; + + /** + * Glyph names for Mac encoding + */ + public static final String MAC_GLYPH_NAMES[] = { + /* 0x00 */ + NOTDEF, ".null", "CR", "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quotesingle", "parenleft", + "parenright", "asterisk", "plus", "comma", /* 0x10 */ + "hyphen", "period", "slash", "zero", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", "colon", + "semicolon", "less", /* 0x20 */ + "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", + "G", "H", "I", "J", "K", "L", /* 0x30 */ + "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "bracketleft", "backslash", /* 0x40 */ + "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", + "d", "e", "f", "g", "h", "i", "j", "k", "l", + /* 0x50 */ + "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "braceleft", "bar", /* 0x60 */ + "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", + "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute", + "agrave", "acircumflex", "adieresis", "atilde", + "aring", "ccedilla", /* 0x70 */ + "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave", + "icircumflex", "idieresis", "ntilde", "oacute", "ograve", + "ocircumflex", "odieresis", "otilde", "uacute", "ugrave", + /* 0x80 */ + "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling", + "section", "bullet", "paragraph", "germandbls", + "registered", "copyright", "trademark", "acute", + "dieresis", "notequal", /* 0x90 */ + "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", + "yen", "mu", "partialdiff", "Sigma", "Pi", "pi", "integral", + "ordfeminine", "ordmasculine", "Omega", /* 0xa0 */ + "ae", "oslash", "questiondown", "exclamdown", "logicalnot", + "radical", "florin", "approxequal", "Delta", "guillemotleft", + "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", /* 0xb0 */ + "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", + "quoteleft", "quoteright", "divide", "lozenge", "ydieresis", + "Ydieresis", "fraction", "currency", "guilsinglleft", + "guilsinglright", /* 0xc0 */ + "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", + "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex", + "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex", + "Idieresis", "Igrave", /* 0xd0 */ + "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute", + "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde", + "macron", "breve", "dotaccent", "ring", "cedilla", + "hungarumlaut", /* 0xe0 */ + "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron", + "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", + "Thorn", "thorn", "minus", /* 0xf0 */ + "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf", + "onequarter", "threequarters", "franc", "Gbreve", + "gbreve", "Idot", "Scedilla", "scedilla", "Cacute", + "cacute", "Ccaron", /* 0x100 */ + "ccaron", "dmacron" + }; + + /** + * Glyph names for tex8r encoding + */ + public static final String[] TEX8R_GLYPH_NAMES = { + // 0x00 + NOTDEF, "dotaccent", "fi", "fl", "fraction", "hungarumlaut", + "Lslash", "lslash", "ogonek", "ring", ".notdef", "breve", + "minus", ".notdef", "Zcaron", "zcaron", // 0x10 + "caron", "dotlessi", "dotlessj", "ff", "ffi", "ffl", ".notdef", + ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", + ".notdef", ".notdef", "grave", "quotesingle", // 0x20 + "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", + "ampersand", "quoteright", "parenleft", "parenright", + "asterisk", "plus", "comma", "hyphen", "period", "slash", + // 0x30 + "zero", "one", "two", "three", "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", "less", "equal", + "greater", "question", // 0x40 + "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", + "M", "N", "O", // 0x50 + "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "asciicircum", "underscore", // 0x60 + "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", + "l", "m", "n", "o", // 0x70 + "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", ".notdef", // 0x80 + "Euro", ".notdef", "quotesinglbase", "florin", "quotedblbase", + "ellipsis", "dagger", "daggerdbl", "circumflex", + "perthousand", "Scaron", "guilsinglleft", "OE", ".notdef", + ".notdef", ".notdef", // 0x90 + ".notdef", ".notdef", ".notdef", "quotedblleft", "quotedblright", + "bullet", "endash", "emdash", "tilde", "trademark", + "scaron", "guilsinglright", "oe", ".notdef", ".notdef", + "Ydieresis", // 0xA0 + ".notdef", "exclamdown", "cent", "sterling", "currency", "yen", + "brokenbar", "section", "dieresis", "copyright", + "ordfeminine", "guillemotleft", "logicalnot", "hyphen", + "registered", "macron", // 0xB0 + "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", + "paragraph", "periodcentered", "cedilla", "onesuperior", + "ordmasculine", "guillemotright", "onequarter", "onehalf", + "threequarters", "questiondown", // 0xC0 + "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring", + "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex", + "Edieresis", "Igrave", "Iacute", "Icircumflex", + "Idieresis", // 0xD0 + "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde", + "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", + "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", + // 0xE0 + "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring", + "ae", "ccedilla", "egrave", "eacute", "ecircumflex", + "edieresis", "igrave", "iacute", "icircumflex", + "idieresis", // 0xF0 + "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde", + "odieresis", "divide", "oslash", "ugrave", "uacute", + "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis" + }; + + /** + * The characters in WinAnsiEncoding + */ + public static final char[] WINANSI_ENCODING = { + // not used until char 32 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 + ' ', '\u0021', '\"', '\u0023', '$', '%', '&', '\'', '(', ')', '*', '+', ',', + '\u002d', '\u002e', '/', // 0x30 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', + '>', '?', '@', // 0x40 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', // 0x50 + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\u005b', '\\', + '\u005d', '^', '_', // 0x60 + '\u2018', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', // 0x70 + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u007b', '\u007c', '\u007d', + '\u007e', '\u2022', // 0x80 + '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', + '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022', + '\u017d', '\u2022', // 0x90 + '\u2022', '\u2018', // quoteleft + '\u2019', // quoteright + '\u201c', // quotedblleft + '\u201d', // quotedblright + '\u2022', // bullet + '\u2013', // endash + '\u2014', // emdash + '~', '\u2022', // bullet + '\u0161', '\u203a', '\u0153', '\u2022', '\u017e', '\u0178', // 0xA0 + ' ', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5', + '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab', + '\u00ac', '\u00ad', '\u00ae', '\u00af', // 0xb0 + '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4', + '\u00b5', // This is hand-coded, the rest is assumption + '\u00b6', // and *might* not be correct... + '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd', + '\u00be', '\u00bf', // 0xc0 + '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', // Aring + '\u00c6', // AE + '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc', + '\u00cd', '\u00ce', '\u00cf', // 0xd0 + '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5', + '\u00d6', '\u00d7', '\u00d8', // Oslash + '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de', + '\u00df', // 0xe0 + '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', // aring + '\u00e6', // ae + '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec', + '\u00ed', '\u00ee', '\u00ef', // 0xf0 + '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5', + '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb', + '\u00fc', '\u00fd', '\u00fe', '\u00ff' + }; + + /** + * List of unicode glyphs + */ + public static final String[] UNICODE_GLYPHS = { + "\u0041", "A", + "\u00C6", "AE", + "\u01FC", "AEacute", + "\uF7E6", "AEsmall", + "\u00C1", "Aacute", + "\uF7E1", "Aacutesmall", + "\u0102", "Abreve", + "\u00C2", "Acircumflex", + "\uF7E2", "Acircumflexsmall", + "\uF6C9", "Acute", + "\uF7B4", "Acutesmall", + "\u00C4", "Adieresis", + "\uF7E4", "Adieresissmall", + "\u00C0", "Agrave", + "\uF7E0", "Agravesmall", + "\u0391", "Alpha", + "\u0386", "Alphatonos", + "\u0100", "Amacron", + "\u0104", "Aogonek", + "\u00C5", "Aring", + "\u01FA", "Aringacute", + "\uF7E5", "Aringsmall", + "\uF761", "Asmall", + "\u00C3", "Atilde", + "\uF7E3", "Atildesmall", + "\u0042", "B", + "\u0392", "Beta", + "\uF6F4", "Brevesmall", + "\uF762", "Bsmall", + "\u0043", "C", + "\u0106", "Cacute", + "\uF6CA", "Caron", + "\uF6F5", "Caronsmall", + "\u010C", "Ccaron", + "\u00C7", "Ccedilla", + "\uF7E7", "Ccedillasmall", + "\u0108", "Ccircumflex", + "\u010A", "Cdotaccent", + "\uF7B8", "Cedillasmall", + "\u03A7", "Chi", + "\uF6F6", "Circumflexsmall", + "\uF763", "Csmall", + "\u0044", "D", + "\u010E", "Dcaron", + "\u0110", "Dcroat", + "\u2206", "Delta", + "\u0394", "Delta", + "\uF6CB", "Dieresis", + "\uF6CC", "DieresisAcute", + "\uF6CD", "DieresisGrave", + "\uF7A8", "Dieresissmall", + "\uF6F7", "Dotaccentsmall", + "\uF764", "Dsmall", + "\u0045", "E", + "\u00C9", "Eacute", + "\uF7E9", "Eacutesmall", + "\u0114", "Ebreve", + "\u011A", "Ecaron", + "\u00CA", "Ecircumflex", + "\uF7EA", "Ecircumflexsmall", + "\u00CB", "Edieresis", + "\uF7EB", "Edieresissmall", + "\u0116", "Edotaccent", + "\u00C8", "Egrave", + "\uF7E8", "Egravesmall", + "\u0112", "Emacron", + "\u014A", "Eng", + "\u0118", "Eogonek", + "\u0395", "Epsilon", + "\u0388", "Epsilontonos", + "\uF765", "Esmall", + "\u0397", "Eta", + "\u0389", "Etatonos", + "\u00D0", "Eth", + "\uF7F0", "Ethsmall", + "\u20AC", "Euro", + "\u0046", "F", + "\uF766", "Fsmall", + "\u0047", "G", + "\u0393", "Gamma", + "\u011E", "Gbreve", + "\u01E6", "Gcaron", + "\u011C", "Gcircumflex", + "\u0122", "Gcommaaccent", + "\u0120", "Gdotaccent", + "\uF6CE", "Grave", + "\uF760", "Gravesmall", + "\uF767", "Gsmall", + "\u0048", "H", + "\u25CF", "H18533", + "\u25AA", "H18543", + "\u25AB", "H18551", + "\u25A1", "H22073", + "\u0126", "Hbar", + "\u0124", "Hcircumflex", + "\uF768", "Hsmall", + "\uF6CF", "Hungarumlaut", + "\uF6F8", "Hungarumlautsmall", + "\u0049", "I", + "\u0132", "IJ", + "\u00CD", "Iacute", + "\uF7ED", "Iacutesmall", + "\u012C", "Ibreve", + "\u00CE", "Icircumflex", + "\uF7EE", "Icircumflexsmall", + "\u00CF", "Idieresis", + "\uF7EF", "Idieresissmall", + "\u0130", "Idotaccent", + "\u2111", "Ifraktur", + "\u00CC", "Igrave", + "\uF7EC", "Igravesmall", + "\u012A", "Imacron", + "\u012E", "Iogonek", + "\u0399", "Iota", + "\u03AA", "Iotadieresis", + "\u038A", "Iotatonos", + "\uF769", "Ismall", + "\u0128", "Itilde", + "\u004A", "J", + "\u0134", "Jcircumflex", + "\uF76A", "Jsmall", + "\u004B", "K", + "\u039A", "Kappa", + "\u0136", "Kcommaaccent", + "\uF76B", "Ksmall", + "\u004C", "L", + "\uF6BF", "LL", + "\u0139", "Lacute", + "\u039B", "Lambda", + "\u013D", "Lcaron", + "\u013B", "Lcommaaccent", + "\u013F", "Ldot", + "\u0141", "Lslash", + "\uF6F9", "Lslashsmall", + "\uF76C", "Lsmall", + "\u004D", "M", + "\uF6D0", "Macron", + "\uF7AF", "Macronsmall", + "\uF76D", "Msmall", + "\u039C", "Mu", + "\u004E", "N", + "\u0143", "Nacute", + "\u0147", "Ncaron", + "\u0145", "Ncommaaccent", + "\uF76E", "Nsmall", + "\u00D1", "Ntilde", + "\uF7F1", "Ntildesmall", + "\u039D", "Nu", + "\u004F", "O", + "\u0152", "OE", + "\uF6FA", "OEsmall", + "\u00D3", "Oacute", + "\uF7F3", "Oacutesmall", + "\u014E", "Obreve", + "\u00D4", "Ocircumflex", + "\uF7F4", "Ocircumflexsmall", + "\u00D6", "Odieresis", + "\uF7F6", "Odieresissmall", + "\uF6FB", "Ogoneksmall", + "\u00D2", "Ograve", + "\uF7F2", "Ogravesmall", + "\u01A0", "Ohorn", + "\u0150", "Ohungarumlaut", + "\u014C", "Omacron", + "\u2126", "Omega", + "\u03A9", "Omega", + "\u038F", "Omegatonos", + "\u039F", "Omicron", + "\u038C", "Omicrontonos", + "\u00D8", "Oslash", + "\u01FE", "Oslashacute", + "\uF7F8", "Oslashsmall", + "\uF76F", "Osmall", + "\u00D5", "Otilde", + "\uF7F5", "Otildesmall", + "\u0050", "P", + "\u03A6", "Phi", + "\u03A0", "Pi", + "\u03A8", "Psi", + "\uF770", "Psmall", + "\u0051", "Q", + "\uF771", "Qsmall", + "\u0052", "R", + "\u0154", "Racute", + "\u0158", "Rcaron", + "\u0156", "Rcommaaccent", + "\u211C", "Rfraktur", + "\u03A1", "Rho", + "\uF6FC", "Ringsmall", + "\uF772", "Rsmall", + "\u0053", "S", + "\u250C", "SF010000", + "\u2514", "SF020000", + "\u2510", "SF030000", + "\u2518", "SF040000", + "\u253C", "SF050000", + "\u252C", "SF060000", + "\u2534", "SF070000", + "\u251C", "SF080000", + "\u2524", "SF090000", + "\u2500", "SF100000", + "\u2502", "SF110000", + "\u2561", "SF190000", + "\u2562", "SF200000", + "\u2556", "SF210000", + "\u2555", "SF220000", + "\u2563", "SF230000", + "\u2551", "SF240000", + "\u2557", "SF250000", + "\u255D", "SF260000", + "\u255C", "SF270000", + "\u255B", "SF280000", + "\u255E", "SF360000", + "\u255F", "SF370000", + "\u255A", "SF380000", + "\u2554", "SF390000", + "\u2569", "SF400000", + "\u2566", "SF410000", + "\u2560", "SF420000", + "\u2550", "SF430000", + "\u256C", "SF440000", + "\u2567", "SF450000", + "\u2568", "SF460000", + "\u2564", "SF470000", + "\u2565", "SF480000", + "\u2559", "SF490000", + "\u2558", "SF500000", + "\u2552", "SF510000", + "\u2553", "SF520000", + "\u256B", "SF530000", + "\u256A", "SF540000", + "\u015A", "Sacute", + "\u0160", "Scaron", + "\uF6FD", "Scaronsmall", + "\u015E", "Scedilla", + "\uF6C1", "Scedilla", + "\u015C", "Scircumflex", + "\u0218", "Scommaaccent", + "\u03A3", "Sigma", + "\uF773", "Ssmall", + "\u0054", "T", + "\u03A4", "Tau", + "\u0166", "Tbar", + "\u0164", "Tcaron", + "\u0162", "Tcommaaccent", + "\u021A", "Tcommaaccent", + "\u0398", "Theta", + "\u00DE", "Thorn", + "\uF7FE", "Thornsmall", + "\uF6FE", "Tildesmall", + "\uF774", "Tsmall", + "\u0055", "U", + "\u00DA", "Uacute", + "\uF7FA", "Uacutesmall", + "\u016C", "Ubreve", + "\u00DB", "Ucircumflex", + "\uF7FB", "Ucircumflexsmall", + "\u00DC", "Udieresis", + "\uF7FC", "Udieresissmall", + "\u00D9", "Ugrave", + "\uF7F9", "Ugravesmall", + "\u01AF", "Uhorn", + "\u0170", "Uhungarumlaut", + "\u016A", "Umacron", + "\u0172", "Uogonek", + "\u03A5", "Upsilon", + "\u03D2", "Upsilon1", + "\u03AB", "Upsilondieresis", + "\u038E", "Upsilontonos", + "\u016E", "Uring", + "\uF775", "Usmall", + "\u0168", "Utilde", + "\u0056", "V", + "\uF776", "Vsmall", + "\u0057", "W", + "\u1E82", "Wacute", + "\u0174", "Wcircumflex", + "\u1E84", "Wdieresis", + "\u1E80", "Wgrave", + "\uF777", "Wsmall", + "\u0058", "X", + "\u039E", "Xi", + "\uF778", "Xsmall", + "\u0059", "Y", + "\u00DD", "Yacute", + "\uF7FD", "Yacutesmall", + "\u0176", "Ycircumflex", + "\u0178", "Ydieresis", + "\uF7FF", "Ydieresissmall", + "\u1EF2", "Ygrave", + "\uF779", "Ysmall", + "\u005A", "Z", + "\u0179", "Zacute", + "\u017D", "Zcaron", + "\uF6FF", "Zcaronsmall", + "\u017B", "Zdotaccent", + "\u0396", "Zeta", + "\uF77A", "Zsmall", + "\u0061", "a", + "\u00E1", "aacute", + "\u0103", "abreve", + "\u00E2", "acircumflex", + "\u00B4", "acute", + "\u0301", "acutecomb", + "\u00E4", "adieresis", + "\u00E6", "ae", + "\u01FD", "aeacute", + "\u2015", "afii00208", + "\u0410", "afii10017", + "\u0411", "afii10018", + "\u0412", "afii10019", + "\u0413", "afii10020", + "\u0414", "afii10021", + "\u0415", "afii10022", + "\u0401", "afii10023", + "\u0416", "afii10024", + "\u0417", "afii10025", + "\u0418", "afii10026", + "\u0419", "afii10027", + "\u041A", "afii10028", + "\u041B", "afii10029", + "\u041C", "afii10030", + "\u041D", "afii10031", + "\u041E", "afii10032", + "\u041F", "afii10033", + "\u0420", "afii10034", + "\u0421", "afii10035", + "\u0422", "afii10036", + "\u0423", "afii10037", + "\u0424", "afii10038", + "\u0425", "afii10039", + "\u0426", "afii10040", + "\u0427", "afii10041", + "\u0428", "afii10042", + "\u0429", "afii10043", + "\u042A", "afii10044", + "\u042B", "afii10045", + "\u042C", "afii10046", + "\u042D", "afii10047", + "\u042E", "afii10048", + "\u042F", "afii10049", + "\u0490", "afii10050", + "\u0402", "afii10051", + "\u0403", "afii10052", + "\u0404", "afii10053", + "\u0405", "afii10054", + "\u0406", "afii10055", + "\u0407", "afii10056", + "\u0408", "afii10057", + "\u0409", "afii10058", + "\u040A", "afii10059", + "\u040B", "afii10060", + "\u040C", "afii10061", + "\u040E", "afii10062", + "\uF6C4", "afii10063", + "\uF6C5", "afii10064", + "\u0430", "afii10065", + "\u0431", "afii10066", + "\u0432", "afii10067", + "\u0433", "afii10068", + "\u0434", "afii10069", + "\u0435", "afii10070", + "\u0451", "afii10071", + "\u0436", "afii10072", + "\u0437", "afii10073", + "\u0438", "afii10074", + "\u0439", "afii10075", + "\u043A", "afii10076", + "\u043B", "afii10077", + "\u043C", "afii10078", + "\u043D", "afii10079", + "\u043E", "afii10080", + "\u043F", "afii10081", + "\u0440", "afii10082", + "\u0441", "afii10083", + "\u0442", "afii10084", + "\u0443", "afii10085", + "\u0444", "afii10086", + "\u0445", "afii10087", + "\u0446", "afii10088", + "\u0447", "afii10089", + "\u0448", "afii10090", + "\u0449", "afii10091", + "\u044A", "afii10092", + "\u044B", "afii10093", + "\u044C", "afii10094", + "\u044D", "afii10095", + "\u044E", "afii10096", + "\u044F", "afii10097", + "\u0491", "afii10098", + "\u0452", "afii10099", + "\u0453", "afii10100", + "\u0454", "afii10101", + "\u0455", "afii10102", + "\u0456", "afii10103", + "\u0457", "afii10104", + "\u0458", "afii10105", + "\u0459", "afii10106", + "\u045A", "afii10107", + "\u045B", "afii10108", + "\u045C", "afii10109", + "\u045E", "afii10110", + "\u040F", "afii10145", + "\u0462", "afii10146", + "\u0472", "afii10147", + "\u0474", "afii10148", + "\uF6C6", "afii10192", + "\u045F", "afii10193", + "\u0463", "afii10194", + "\u0473", "afii10195", + "\u0475", "afii10196", + "\uF6C7", "afii10831", + "\uF6C8", "afii10832", + "\u04D9", "afii10846", + "\u200E", "afii299", + "\u200F", "afii300", + "\u200D", "afii301", + "\u066A", "afii57381", + "\u060C", "afii57388", + "\u0660", "afii57392", + "\u0661", "afii57393", + "\u0662", "afii57394", + "\u0663", "afii57395", + "\u0664", "afii57396", + "\u0665", "afii57397", + "\u0666", "afii57398", + "\u0667", "afii57399", + "\u0668", "afii57400", + "\u0669", "afii57401", + "\u061B", "afii57403", + "\u061F", "afii57407", + "\u0621", "afii57409", + "\u0622", "afii57410", + "\u0623", "afii57411", + "\u0624", "afii57412", + "\u0625", "afii57413", + "\u0626", "afii57414", + "\u0627", "afii57415", + "\u0628", "afii57416", + "\u0629", "afii57417", + "\u062A", "afii57418", + "\u062B", "afii57419", + "\u062C", "afii57420", + "\u062D", "afii57421", + "\u062E", "afii57422", + "\u062F", "afii57423", + "\u0630", "afii57424", + "\u0631", "afii57425", + "\u0632", "afii57426", + "\u0633", "afii57427", + "\u0634", "afii57428", + "\u0635", "afii57429", + "\u0636", "afii57430", + "\u0637", "afii57431", + "\u0638", "afii57432", + "\u0639", "afii57433", + "\u063A", "afii57434", + "\u0640", "afii57440", + "\u0641", "afii57441", + "\u0642", "afii57442", + "\u0643", "afii57443", + "\u0644", "afii57444", + "\u0645", "afii57445", + "\u0646", "afii57446", + "\u0648", "afii57448", + "\u0649", "afii57449", + "\u064A", "afii57450", + "\u064B", "afii57451", + "\u064C", "afii57452", + "\u064D", "afii57453", + "\u064E", "afii57454", + "\u064F", "afii57455", + "\u0650", "afii57456", + "\u0651", "afii57457", + "\u0652", "afii57458", + "\u0647", "afii57470", + "\u06A4", "afii57505", + "\u067E", "afii57506", + "\u0686", "afii57507", + "\u0698", "afii57508", + "\u06AF", "afii57509", + "\u0679", "afii57511", + "\u0688", "afii57512", + "\u0691", "afii57513", + "\u06BA", "afii57514", + "\u06D2", "afii57519", + "\u06D5", "afii57534", + "\u20AA", "afii57636", + "\u05BE", "afii57645", + "\u05C3", "afii57658", + "\u05D0", "afii57664", + "\u05D1", "afii57665", + "\u05D2", "afii57666", + "\u05D3", "afii57667", + "\u05D4", "afii57668", + "\u05D5", "afii57669", + "\u05D6", "afii57670", + "\u05D7", "afii57671", + "\u05D8", "afii57672", + "\u05D9", "afii57673", + "\u05DA", "afii57674", + "\u05DB", "afii57675", + "\u05DC", "afii57676", + "\u05DD", "afii57677", + "\u05DE", "afii57678", + "\u05DF", "afii57679", + "\u05E0", "afii57680", + "\u05E1", "afii57681", + "\u05E2", "afii57682", + "\u05E3", "afii57683", + "\u05E4", "afii57684", + "\u05E5", "afii57685", + "\u05E6", "afii57686", + "\u05E7", "afii57687", + "\u05E8", "afii57688", + "\u05E9", "afii57689", + "\u05EA", "afii57690", + "\uFB2A", "afii57694", + "\uFB2B", "afii57695", + "\uFB4B", "afii57700", + "\uFB1F", "afii57705", + "\u05F0", "afii57716", + "\u05F1", "afii57717", + "\u05F2", "afii57718", + "\uFB35", "afii57723", + "\u05B4", "afii57793", + "\u05B5", "afii57794", + "\u05B6", "afii57795", + "\u05BB", "afii57796", + "\u05B8", "afii57797", + "\u05B7", "afii57798", + "\u05B0", "afii57799", + "\u05B2", "afii57800", + "\u05B1", "afii57801", + "\u05B3", "afii57802", + "\u05C2", "afii57803", + "\u05C1", "afii57804", + "\u05B9", "afii57806", + "\u05BC", "afii57807", + "\u05BD", "afii57839", + "\u05BF", "afii57841", + "\u05C0", "afii57842", + "\u02BC", "afii57929", + "\u2105", "afii61248", + "\u2113", "afii61289", + "\u2116", "afii61352", + "\u202C", "afii61573", + "\u202D", "afii61574", + "\u202E", "afii61575", + "\u200C", "afii61664", + "\u066D", "afii63167", + "\u02BD", "afii64937", + "\u00E0", "agrave", + "\u2135", "aleph", + "\u03B1", "alpha", + "\u03AC", "alphatonos", + "\u0101", "amacron", + "\u0026", "ampersand", + "\uF726", "ampersandsmall", + "\u2220", "angle", + "\u2329", "angleleft", + "\u232A", "angleright", + "\u0387", "anoteleia", + "\u0105", "aogonek", + "\u2248", "approxequal", + "\u00E5", "aring", + "\u01FB", "aringacute", + "\u2194", "arrowboth", + "\u21D4", "arrowdblboth", + "\u21D3", "arrowdbldown", + "\u21D0", "arrowdblleft", + "\u21D2", "arrowdblright", + "\u21D1", "arrowdblup", + "\u2193", "arrowdown", + "\uF8E7", "arrowhorizex", + "\u2190", "arrowleft", + "\u2192", "arrowright", + "\u2191", "arrowup", + "\u2195", "arrowupdn", + "\u21A8", "arrowupdnbse", + "\uF8E6", "arrowvertex", + "\u005E", "asciicircum", + "\u007E", "asciitilde", + "\u002A", "asterisk", + "\u2217", "asteriskmath", + "\uF6E9", "asuperior", + "\u0040", "at", + "\u00E3", "atilde", + "\u0062", "b", + //"\u005C", "backslash", + "\\", "backslash", + "\u007C", "bar", + "\u03B2", "beta", + "\u2588", "block", + "\uF8F4", "braceex", + "\u007B", "braceleft", + "\uF8F3", "braceleftbt", + "\uF8F2", "braceleftmid", + "\uF8F1", "bracelefttp", + "\u007D", "braceright", + "\uF8FE", "bracerightbt", + "\uF8FD", "bracerightmid", + "\uF8FC", "bracerighttp", + "\u005B", "bracketleft", + "\uF8F0", "bracketleftbt", + "\uF8EF", "bracketleftex", + "\uF8EE", "bracketlefttp", + "\u005D", "bracketright", + "\uF8FB", "bracketrightbt", + "\uF8FA", "bracketrightex", + "\uF8F9", "bracketrighttp", + "\u02D8", "breve", + "\u00A6", "brokenbar", + "\uF6EA", "bsuperior", + "\u2022", "bullet", + "\u0063", "c", + "\u0107", "cacute", + "\u02C7", "caron", + "\u21B5", "carriagereturn", + "\u010D", "ccaron", + "\u00E7", "ccedilla", + "\u0109", "ccircumflex", + "\u010B", "cdotaccent", + "\u00B8", "cedilla", + "\u00A2", "cent", + "\uF6DF", "centinferior", + "\uF7A2", "centoldstyle", + "\uF6E0", "centsuperior", + "\u03C7", "chi", + "\u25CB", "circle", + "\u2297", "circlemultiply", + "\u2295", "circleplus", + "\u02C6", "circumflex", + "\u2663", "club", + "\u003A", "colon", + "\u20A1", "colonmonetary", + "\u002C", "comma", + "\uF6C3", "commaaccent", + "\uF6E1", "commainferior", + "\uF6E2", "commasuperior", + "\u2245", "congruent", + "\u00A9", "copyright", + "\uF8E9", "copyrightsans", + "\uF6D9", "copyrightserif", + "\u00A4", "currency", + "\uF6D1", "cyrBreve", + "\uF6D2", "cyrFlex", + "\uF6D4", "cyrbreve", + "\uF6D5", "cyrflex", + "\u0064", "d", + "\u2020", "dagger", + "\u2021", "daggerdbl", + "\uF6D3", "dblGrave", + "\uF6D6", "dblgrave", + "\u010F", "dcaron", + "\u0111", "dcroat", + "\u00B0", "degree", + "\u03B4", "delta", + "\u2666", "diamond", + "\u00A8", "dieresis", + "\uF6D7", "dieresisacute", + "\uF6D8", "dieresisgrave", + "\u0385", "dieresistonos", + "\u00F7", "divide", + "\u2593", "dkshade", + "\u2584", "dnblock", + "\u0024", "dollar", + "\uF6E3", "dollarinferior", + "\uF724", "dollaroldstyle", + "\uF6E4", "dollarsuperior", + "\u20AB", "dong", + "\u02D9", "dotaccent", + "\u0323", "dotbelowcomb", + "\u0131", "dotlessi", + "\uF6BE", "dotlessj", + "\u22C5", "dotmath", + "\uF6EB", "dsuperior", + "\u0065", "e", + "\u00E9", "eacute", + "\u0115", "ebreve", + "\u011B", "ecaron", + "\u00EA", "ecircumflex", + "\u00EB", "edieresis", + "\u0117", "edotaccent", + "\u00E8", "egrave", + "\u0038", "eight", + "\u2088", "eightinferior", + "\uF738", "eightoldstyle", + "\u2078", "eightsuperior", + "\u2208", "element", + "\u2026", "ellipsis", + "\u0113", "emacron", + "\u2014", "emdash", + "\u2205", "emptyset", + "\u2013", "endash", + "\u014B", "eng", + "\u0119", "eogonek", + "\u03B5", "epsilon", + "\u03AD", "epsilontonos", + "\u003D", "equal", + "\u2261", "equivalence", + "\u212E", "estimated", + "\uF6EC", "esuperior", + "\u03B7", "eta", + "\u03AE", "etatonos", + "\u00F0", "eth", + "\u0021", "exclam", + "\u203C", "exclamdbl", + "\u00A1", "exclamdown", + "\uF7A1", "exclamdownsmall", + "\uF721", "exclamsmall", + "\u2203", "existential", + "\u0066", "f", + "\u2640", "female", + "\uFB00", "ff", + "\uFB03", "ffi", + "\uFB04", "ffl", + "\uFB01", "fi", + "\u2012", "figuredash", + "\u25A0", "filledbox", + "\u25AC", "filledrect", + "\u0035", "five", + "\u215D", "fiveeighths", + "\u2085", "fiveinferior", + "\uF735", "fiveoldstyle", + "\u2075", "fivesuperior", + "\uFB02", "fl", + "\u0192", "florin", + "\u0034", "four", + "\u2084", "fourinferior", + "\uF734", "fouroldstyle", + "\u2074", "foursuperior", + "\u2044", "fraction", + "\u2215", "fraction", + "\u20A3", "franc", + "\u0067", "g", + "\u03B3", "gamma", + "\u011F", "gbreve", + "\u01E7", "gcaron", + "\u011D", "gcircumflex", + "\u0123", "gcommaaccent", + "\u0121", "gdotaccent", + "\u00DF", "germandbls", + "\u2207", "gradient", + "\u0060", "grave", + "\u0300", "gravecomb", + "\u003E", "greater", + "\u2265", "greaterequal", + "\u00AB", "guillemotleft", + "\u00BB", "guillemotright", + "\u2039", "guilsinglleft", + "\u203A", "guilsinglright", + "\u0068", "h", + "\u0127", "hbar", + "\u0125", "hcircumflex", + "\u2665", "heart", + "\u0309", "hookabovecomb", + "\u2302", "house", + "\u02DD", "hungarumlaut", + "\u002D", "hyphen", + "\u00AD", "hyphen", + "\uF6E5", "hypheninferior", + "\uF6E6", "hyphensuperior", + "\u0069", "i", + "\u00ED", "iacute", + "\u012D", "ibreve", + "\u00EE", "icircumflex", + "\u00EF", "idieresis", + "\u00EC", "igrave", + "\u0133", "ij", + "\u012B", "imacron", + "\u221E", "infinity", + "\u222B", "integral", + "\u2321", "integralbt", + "\uF8F5", "integralex", + "\u2320", "integraltp", + "\u2229", "intersection", + "\u25D8", "invbullet", + "\u25D9", "invcircle", + "\u263B", "invsmileface", + "\u012F", "iogonek", + "\u03B9", "iota", + "\u03CA", "iotadieresis", + "\u0390", "iotadieresistonos", + "\u03AF", "iotatonos", + "\uF6ED", "isuperior", + "\u0129", "itilde", + "\u006A", "j", + "\u0135", "jcircumflex", + "\u006B", "k", + "\u03BA", "kappa", + "\u0137", "kcommaaccent", + "\u0138", "kgreenlandic", + "\u006C", "l", + "\u013A", "lacute", + "\u03BB", "lambda", + "\u013E", "lcaron", + "\u013C", "lcommaaccent", + "\u0140", "ldot", + "\u003C", "less", + "\u2264", "lessequal", + "\u258C", "lfblock", + "\u20A4", "lira", + "\uF6C0", "ll", + "\u2227", "logicaland", + "\u00AC", "logicalnot", + "\u2228", "logicalor", + "\u017F", "longs", + "\u25CA", "lozenge", + "\u0142", "lslash", + "\uF6EE", "lsuperior", + "\u2591", "ltshade", + "\u006D", "m", + "\u00AF", "macron", + "\u02C9", "macron", + "\u2642", "male", + "\u2212", "minus", + "\u2032", "minute", + "\uF6EF", "msuperior", + "\u00B5", "mu", + "\u03BC", "mu", + "\u00D7", "multiply", + "\u266A", "musicalnote", + "\u266B", "musicalnotedbl", + "\u006E", "n", + "\u0144", "nacute", + "\u0149", "napostrophe", + "\u0148", "ncaron", + "\u0146", "ncommaaccent", + "\u0039", "nine", + "\u2089", "nineinferior", + "\uF739", "nineoldstyle", + "\u2079", "ninesuperior", + "\u2209", "notelement", + "\u2260", "notequal", + "\u2284", "notsubset", + "\u207F", "nsuperior", + "\u00F1", "ntilde", + "\u03BD", "nu", + "\u0023", "numbersign", + "\u006F", "o", + "\u00F3", "oacute", + "\u014F", "obreve", + "\u00F4", "ocircumflex", + "\u00F6", "odieresis", + "\u0153", "oe", + "\u02DB", "ogonek", + "\u00F2", "ograve", + "\u01A1", "ohorn", + "\u0151", "ohungarumlaut", + "\u014D", "omacron", + "\u03C9", "omega", + "\u03D6", "omega1", + "\u03CE", "omegatonos", + "\u03BF", "omicron", + "\u03CC", "omicrontonos", + "\u0031", "one", + "\u2024", "onedotenleader", + "\u215B", "oneeighth", + "\uF6DC", "onefitted", + "\u00BD", "onehalf", + "\u2081", "oneinferior", + "\uF731", "oneoldstyle", + "\u00BC", "onequarter", + "\u00B9", "onesuperior", + "\u2153", "onethird", + "\u25E6", "openbullet", + "\u00AA", "ordfeminine", + "\u00BA", "ordmasculine", + "\u221F", "orthogonal", + "\u00F8", "oslash", + "\u01FF", "oslashacute", + "\uF6F0", "osuperior", + "\u00F5", "otilde", + "\u0070", "p", + "\u00B6", "paragraph", + "\u0028", "parenleft", + "\uF8ED", "parenleftbt", + "\uF8EC", "parenleftex", + "\u208D", "parenleftinferior", + "\u207D", "parenleftsuperior", + "\uF8EB", "parenlefttp", + "\u0029", "parenright", + "\uF8F8", "parenrightbt", + "\uF8F7", "parenrightex", + "\u208E", "parenrightinferior", + "\u207E", "parenrightsuperior", + "\uF8F6", "parenrighttp", + "\u2202", "partialdiff", + "\u0025", "percent", + "\u002E", "period", + "\u00B7", "periodcentered", + "\u2219", "periodcentered", + "\uF6E7", "periodinferior", + "\uF6E8", "periodsuperior", + "\u22A5", "perpendicular", + "\u2030", "perthousand", + "\u20A7", "peseta", + "\u03C6", "phi", + "\u03D5", "phi1", + "\u03C0", "pi", + "\u002B", "plus", + "\u00B1", "plusminus", + "\u211E", "prescription", + "\u220F", "product", + "\u2282", "propersubset", + "\u2283", "propersuperset", + "\u221D", "proportional", + "\u03C8", "psi", + "\u0071", "q", + "\u003F", "question", + "\u00BF", "questiondown", + "\uF7BF", "questiondownsmall", + "\uF73F", "questionsmall", + "\"", "quotedbl", +// "\u0022", "quotedbl", + "\u201E", "quotedblbase", + "\u201C", "quotedblleft", + "\u201D", "quotedblright", + "\u2018", "quoteleft", + "\u201B", "quotereversed", + "\u2019", "quoteright", + "\u201A", "quotesinglbase", + "\u0027", "quotesingle", + "\u0072", "r", + "\u0155", "racute", + "\u221A", "radical", + "\uF8E5", "radicalex", + "\u0159", "rcaron", + "\u0157", "rcommaaccent", + "\u2286", "reflexsubset", + "\u2287", "reflexsuperset", + "\u00AE", "registered", + "\uF8E8", "registersans", + "\uF6DA", "registerserif", + "\u2310", "revlogicalnot", + "\u03C1", "rho", + "\u02DA", "ring", + "\uF6F1", "rsuperior", + "\u2590", "rtblock", + "\uF6DD", "rupiah", + "\u0073", "s", + "\u015B", "sacute", + "\u0161", "scaron", + "\u015F", "scedilla", + "\uF6C2", "scedilla", + "\u015D", "scircumflex", + "\u0219", "scommaaccent", + "\u2033", "second", + "\u00A7", "section", + "\u003B", "semicolon", + "\u0037", "seven", + "\u215E", "seveneighths", + "\u2087", "seveninferior", + "\uF737", "sevenoldstyle", + "\u2077", "sevensuperior", + "\u2592", "shade", + "\u03C3", "sigma", + "\u03C2", "sigma1", + "\u223C", "similar", + "\u0036", "six", + "\u2086", "sixinferior", + "\uF736", "sixoldstyle", + "\u2076", "sixsuperior", + "\u002F", "slash", + "\u263A", "smileface", + "\u0020", "space", + "\u00A0", "space", + "\u2660", "spade", + "\uF6F2", "ssuperior", + "\u00A3", "sterling", + "\u220B", "suchthat", + "\u2211", "summation", + "\u263C", "sun", + "\u0074", "t", + "\u03C4", "tau", + "\u0167", "tbar", + "\u0165", "tcaron", + "\u0163", "tcommaaccent", + "\u021B", "tcommaaccent", + "\u2234", "therefore", + "\u03B8", "theta", + "\u03D1", "theta1", + "\u00FE", "thorn", + "\u0033", "three", + "\u215C", "threeeighths", + "\u2083", "threeinferior", + "\uF733", "threeoldstyle", + "\u00BE", "threequarters", + "\uF6DE", "threequartersemdash", + "\u00B3", "threesuperior", + "\u02DC", "tilde", + "\u0303", "tildecomb", + "\u0384", "tonos", + "\u2122", "trademark", + "\uF8EA", "trademarksans", + "\uF6DB", "trademarkserif", + "\u25BC", "triagdn", + "\u25C4", "triaglf", + "\u25BA", "triagrt", + "\u25B2", "triagup", + "\uF6F3", "tsuperior", + "\u0032", "two", + "\u2025", "twodotenleader", + "\u2082", "twoinferior", + "\uF732", "twooldstyle", + "\u00B2", "twosuperior", + "\u2154", "twothirds", + "\u0075", "u", + "\u00FA", "uacute", + "\u016D", "ubreve", + "\u00FB", "ucircumflex", + "\u00FC", "udieresis", + "\u00F9", "ugrave", + "\u01B0", "uhorn", + "\u0171", "uhungarumlaut", + "\u016B", "umacron", + "\u005F", "underscore", + "\u2017", "underscoredbl", + "\u222A", "union", + "\u2200", "universal", + "\u0173", "uogonek", + "\u2580", "upblock", + "\u03C5", "upsilon", + "\u03CB", "upsilondieresis", + "\u03B0", "upsilondieresistonos", + "\u03CD", "upsilontonos", + "\u016F", "uring", + "\u0169", "utilde", + "\u0076", "v", + "\u0077", "w", + "\u1E83", "wacute", + "\u0175", "wcircumflex", + "\u1E85", "wdieresis", + "\u2118", "weierstrass", + "\u1E81", "wgrave", + "\u0078", "x", + "\u03BE", "xi", + "\u0079", "y", + "\u00FD", "yacute", + "\u0177", "ycircumflex", + "\u00FF", "ydieresis", + "\u00A5", "yen", + "\u1EF3", "ygrave", + "\u007A", "z", + "\u017A", "zacute", + "\u017E", "zcaron", + "\u017C", "zdotaccent", + "\u0030", "zero", + "\u2080", "zeroinferior", + "\uF730", "zerooldstyle", + "\u2070", "zerosuperior", + "\u03B6", "zeta" + }; + + /** + * Return the glyphname from a string, + * eg, glyphToString("\\") returns "backslash" + * + * @param name glyph to evaluate + * @return the name of the glyph + */ + public static final String glyphToString(String name) { + for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) { + if (UNICODE_GLYPHS[i + 1].equals(name)) { + return UNICODE_GLYPHS[i]; + } + } + return ""; + } + + /** + * Return the string representation of a glyphname, + * eg stringToGlyph("backslash") returns "\\" + * + * @param name name of the glyph + * @return the string representation + */ + public static String stringToGlyph(String name) { + for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) { + if (UNICODE_GLYPHS[i].equals(name)) { + return UNICODE_GLYPHS[i + 1]; + } + } + return ""; + } + +} + diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java new file mode 100644 index 000000000..5534d1e55 --- /dev/null +++ b/src/java/org/apache/fop/fonts/LazyFont.java @@ -0,0 +1,287 @@ +/* + * $Id: LazyFont.java,v 1.3 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +//Java +import java.util.Map; + +//FOP +import org.apache.fop.render.pdf.FontReader; + +/** + * This class is used to defer the loading of a font until it is really used. + */ +public class LazyFont extends Font implements FontDescriptor { + + private String metricsFileName = null; + private String fontEmbedPath = null; + private boolean useKerning = false; + + private boolean isMetricsLoaded = false; + private Font realFont = null; + private FontDescriptor realFontDescriptor = null; + + /** + * Main constructor + * @param fontEmbedPath path to embeddable file (may be null) + * @param metricsFileName path to the metrics XML file + * @param useKerning True, if kerning should be enabled + */ + public LazyFont(String fontEmbedPath, String metricsFileName, boolean useKerning) { + this.metricsFileName = metricsFileName; + this.fontEmbedPath = fontEmbedPath; + this.useKerning = useKerning; + } + + private void load() { + if (!isMetricsLoaded) { + isMetricsLoaded = true; + try { + /**@todo Possible thread problem here */ + + FontReader reader = new FontReader(metricsFileName); + reader.setKerningEnabled(useKerning); + reader.setFontEmbedPath(fontEmbedPath); + realFont = reader.getFont(); + if (realFont instanceof FontDescriptor) { + realFontDescriptor = (FontDescriptor) realFont; + } + // System.out.println("Metrics " + metricsFileName + " loaded."); + } catch (Exception ex) { + /**@todo Log this exception */ + //log.error("Failed to read font metrics file " + // + metricsFileName + // + " : " + ex.getMessage()); + } + } + } + + /** + * Gets the real font. + * @return the real font + */ + public Font getRealFont() { + load(); + return realFont; + } + + // ---- Font ---- + /** + * @see org.apache.fop.fonts.Font#getEncoding() + */ + public String getEncoding() { + load(); + return realFont.getEncoding(); + } + + /** + * @see org.apache.fop.fonts.Font#mapChar(char) + */ + public char mapChar(char c) { + load(); + return realFont.mapChar(c); + } + + /** + * @see org.apache.fop.fonts.Font#isMultiByte() + */ + public boolean isMultiByte() { + return realFont.isMultiByte(); + } + + // ---- FontMetrics interface ---- + /** + * @see org.apache.fop.fonts.FontMetrics#getFontName() + */ + public String getFontName() { + load(); + return realFont.getFontName(); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getAscender(int) + */ + public int getAscender(int size) { + load(); + return realFont.getAscender(size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int) + */ + public int getCapHeight(int size) { + load(); + return realFont.getCapHeight(size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getDescender(int) + */ + public int getDescender(int size) { + load(); + return realFont.getDescender(size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getXHeight(int) + */ + public int getXHeight(int size) { + load(); + return realFont.getXHeight(size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int) + */ + public int getWidth(int i, int size) { + load(); + return realFont.getWidth(i, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidths() + */ + public int[] getWidths() { + load(); + return realFont.getWidths(); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo() + */ + public boolean hasKerningInfo() { + load(); + return realFont.hasKerningInfo(); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getKerningInfo() + */ + public Map getKerningInfo() { + load(); + return realFont.getKerningInfo(); + } + + // ---- FontDescriptor interface ---- + /** + * @see org.apache.fop.fonts.FontDescriptor#getCapHeight() + */ + public int getCapHeight() { + load(); + return realFontDescriptor.getCapHeight(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getDescender() + */ + public int getDescender() { + load(); + return realFontDescriptor.getDescender(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getAscender() + */ + public int getAscender() { + load(); + return realFontDescriptor.getAscender(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFlags() + */ + public int getFlags() { + load(); + return realFontDescriptor.getFlags(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFontBBox() + */ + public int[] getFontBBox() { + load(); + return realFontDescriptor.getFontBBox(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getItalicAngle() + */ + public int getItalicAngle() { + load(); + return realFontDescriptor.getItalicAngle(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getStemV() + */ + public int getStemV() { + load(); + return realFontDescriptor.getStemV(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#getFontType() + */ + public FontType getFontType() { + load(); + return realFontDescriptor.getFontType(); + } + + /** + * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable() + */ + public boolean isEmbeddable() { + load(); + return realFontDescriptor.isEmbeddable(); + } + +} + diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java new file mode 100644 index 000000000..91694051e --- /dev/null +++ b/src/java/org/apache/fop/fonts/MultiByteFont.java @@ -0,0 +1,359 @@ +/* + * $Id: MultiByteFont.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +//Java +import java.util.Map; + +//FOP +import org.apache.fop.pdf.PDFWArray; + +/** + * Generic MultiByte (CID) font + */ +public class MultiByteFont extends CIDFont { + + private static int uniqueCounter = 1; + + + private String ttcName = null; + private String encoding = "Identity-H"; + + private String embedResourceName = null; + + private int defaultWidth = 0; + private CIDFontType cidType = CIDFontType.CIDTYPE2; + + private String namePrefix = null; // Quasi unique prefix + private PDFWArray warray = new PDFWArray(); + private int width[] = null; + + private BFEntry[] bfentries = null; + + /** + * usedGlyphs contains orginal, new glyph index + */ + private Map usedGlyphs = new java.util.HashMap(); + + /** + * usedGlyphsIndex contains new glyph, original index + */ + private Map usedGlyphsIndex = new java.util.HashMap(); + private int usedGlyphsCount = 0; + + + /** + * Default constructor + */ + public MultiByteFont() { + // Make sure that the 3 first glyphs are included + usedGlyphs.put(new Integer(0), new Integer(0)); + usedGlyphsIndex.put(new Integer(0), new Integer(0)); + usedGlyphsCount++; + usedGlyphs.put(new Integer(1), new Integer(1)); + usedGlyphsIndex.put(new Integer(1), new Integer(1)); + usedGlyphsCount++; + usedGlyphs.put(new Integer(2), new Integer(2)); + usedGlyphsIndex.put(new Integer(2), new Integer(2)); + usedGlyphsCount++; + + // Create a quasiunique prefix for fontname + int cnt = 0; + synchronized (this.getClass()) { + cnt = uniqueCounter++; + } + int ctm = (int)(System.currentTimeMillis() & 0xffff); + namePrefix = new String(cnt + "E" + Integer.toHexString(ctm)); + + setFontType(FontType.TYPE0); + } + + /** + * @see org.apache.fop.fonts.CIDFont#getDefaultWidth() + */ + public int getDefaultWidth() { + return defaultWidth; + } + + /** + * @see org.apache.fop.fonts.CIDFont#getRegistry() + */ + public String getRegistry() { + return "Adobe"; + } + + /** + * @see org.apache.fop.fonts.CIDFont#getOrdering() + */ + public String getOrdering() { + return "UCS"; + } + + /** + * @see org.apache.fop.fonts.CIDFont#getSupplement() + */ + public int getSupplement() { + return 0; + } + + /** + * @see org.apache.fop.fonts.CIDFont#getCIDType() + */ + public CIDFontType getCIDType() { + return cidType; + } + + /** + * Sets the CIDType. + * @param cidType The cidType to set + */ + public void setCIDType(CIDFontType cidType) { + this.cidType = cidType; + } + + /** + * @see org.apache.fop.fonts.CIDFont#getCidBaseFont() + */ + public String getCidBaseFont() { + if (isEmbeddable()) { + return namePrefix + super.getFontName(); + } else { + return super.getFontName(); + } + } + +/* unused + public PDFWArray getWidthsAsPDFWArray() { + if (isEmbeddable()) { + // Create widths for reencoded chars + warray = new PDFWArray(); + int[] tmpWidth = new int[usedGlyphsCount]; + + for (int i = 0; i < usedGlyphsCount; i++) { + Integer nw = (Integer)usedGlyphsIndex.get(new Integer(i)); + int nwx = (nw == null) ? 0 : nw.intValue(); + tmpWidth[i] = width[nwx]; + } + warray.addEntry(0, tmpWidth); + } + return warray; + }*/ + + /** + * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable() + */ + public boolean isEmbeddable() { + if (getEmbedFileName() == null + && embedResourceName == null) { + return false; + } else { + return true; + } + } + + /** + * @see org.apache.fop.fonts.Font#getEncoding() + */ + public String getEncoding() { + return encoding; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getFontName() + */ + public String getFontName() { + if (isEmbeddable()) { + return namePrefix + super.getFontName(); + } else { + return super.getFontName(); + } + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int) + */ + public int getWidth(int i, int size) { + if (isEmbeddable()) { + Integer idx = (Integer)usedGlyphsIndex.get(new Integer(i)); + return size * width[idx.intValue()]; + } else { + return size * width[i]; + } + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidths() + */ + public int[] getWidths() { + int[] arr = new int[width.length]; + System.arraycopy(width, 0, arr, 0, width.length - 1); + /* + for (int i = 0; i < arr.length; i++) + arr[i] *= size; + */ + return arr; + } + + /** + * Remaps a codepoint based. + * @param i codepoint to remap + * @return new codepoint + */ +/* unused + public Integer reMap(Integer i) { + if (isEmbeddable()) { + Integer ret = (Integer)usedGlyphsIndex.get(i); + if (ret == null) { + ret = i; + } + return ret; + } else { + return i; + } + + } +*/ + + /** + * @see org.apache.fop.fonts.Font#mapChar(char) + */ + public char mapChar(char c) { + int idx = (int)c; + int retIdx = 0; + + for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) { + if (bfentries[i].getUnicodeStart() <= idx + && bfentries[i].getUnicodeEnd() >= idx) { + retIdx = bfentries[i].getGlyphStartIndex() + idx + - bfentries[i].getUnicodeStart(); + } + } + + if (isEmbeddable()) { + // Reencode to a new subset font or get + // the reencoded value + Integer newIdx = (Integer)usedGlyphs.get(new Integer(retIdx)); + if (newIdx == null) { + usedGlyphs.put(new Integer(retIdx), + new Integer(usedGlyphsCount)); + usedGlyphsIndex.put(new Integer(usedGlyphsCount), + new Integer(retIdx)); + retIdx = usedGlyphsCount; + // System.out.println(c+"("+(int)c+") = "+retIdx); + usedGlyphsCount++; + } else { + retIdx = newIdx.intValue(); + } + } + + return (char)retIdx; + } + + /** + * Sets the bfentries. + * @param bfentries The bfentries to set + */ + public void setBFEntries(BFEntry[] bfentries) { + this.bfentries = bfentries; + } + + /** + * Sets the defaultWidth. + * @param defaultWidth The defaultWidth to set + */ + public void setDefaultWidth(int defaultWidth) { + this.defaultWidth = defaultWidth; + } + + /** + * Returns the TrueType Collection Name. + * @return the TrueType Collection Name + */ + public String getTTCName() { + return ttcName; + } + + /** + * Sets the the TrueType Collection Name. + * @param ttcName the TrueType Collection Name + */ + public void setTTCName(String ttcName) { + this.ttcName = ttcName; + } + + /** + * Adds a new CID width entry to the font. + * @param cidWidthIndex index + * @param wds array of widths + */ + public void addCIDWidthEntry(int cidWidthIndex, int[] wds) { + this.warray.addEntry(cidWidthIndex, wds); + } + + + /** + * Sets the width array. + * @param wds array of widths. + */ + public void setWidthArray(int[] wds) { + this.width = wds; + } + + /** + * Returns a Map of used Glyphs. + * @return Map Map of used Glyphs + */ + public Map getUsedGlyphs() { + return usedGlyphs; + } + +} + diff --git a/src/java/org/apache/fop/fonts/MutableFont.java b/src/java/org/apache/fop/fonts/MutableFont.java new file mode 100644 index 000000000..ee27baab2 --- /dev/null +++ b/src/java/org/apache/fop/fonts/MutableFont.java @@ -0,0 +1,158 @@ +/* + * $Id: MutableFont.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +import java.util.Map; + + +/** + * This interface is used to set the values of a font during configuration time. + */ +public interface MutableFont { + + /** + * Sets the font name. + * @param name font name + */ + void setFontName(String name); + + /** + * Sets the path to the embeddable font file. + * @param path URI to the file + */ + void setEmbedFileName(String path); + + /** + * Sets the resource name of the embeddable font file. + * @param name resource name + */ + void setEmbedResourceName(String name); + + /** + * Sets the capital height value. + * @param capHeight capital height + */ + void setCapHeight(int capHeight); + + /** + * Sets the ascent value. + * @param ascender ascent height + */ + void setAscender(int ascender); + + /** + * Sets the descent value. + * @param descender descent value + */ + void setDescender(int descender); + + /** + * Sets the font's bounding box + * @param bbox bounding box + */ + void setFontBBox(int[] bbox); + + /** + * Sets the font's flags + * @param flags flags + */ + void setFlags(int flags); + + /** + * Sets the font's StemV value. + * @param stemV StemV + */ + void setStemV(int stemV); + + /** + * Sets the font's italic angle. + * @param italicAngle italic angle + */ + void setItalicAngle(int italicAngle); + + /** + * Sets the font's default width + * @param width default width + */ + void setMissingWidth(int width); + + /** + * Sets the font type. + * @param fontType font type + */ + void setFontType(FontType fontType); + + /** + * Sets the index of the first character in the character table. + * @param index index of first character + */ + void setFirstChar(int index); + + /** + * Sets the index of the last character in the character table. + * @param index index of the last character + */ + void setLastChar(int index); + + /** + * Enables/disabled kerning. + * @param enabled True if kerning should be enabled if available + */ + void setKerningEnabled(boolean enabled); + + /** + * Adds an entry to the kerning table. + * @param key Kerning key + * @param value Kerning value + */ + void putKerningEntry(Integer key, Map value); + +} diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java new file mode 100644 index 000000000..fac9f65a1 --- /dev/null +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -0,0 +1,128 @@ +/* + * $Id: SingleByteFont.java,v 1.2 2003/03/06 17:43:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts; + +/** + * Generic SingleByte font + */ +public class SingleByteFont extends CustomFont { + + private final CodePointMapping mapping + = CodePointMapping.getMapping("WinAnsiEncoding"); + + private String encoding = "WinAnsiEncoding"; + + private int width[] = null; + + + /** + * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable() + */ + public boolean isEmbeddable() { + return (getEmbedFileName() == null && getEmbedResourceName() == null) ? false + : true; + } + + /** + * @see org.apache.fop.fonts.Font#getEncoding() + */ + public String getEncoding() { + return encoding; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int) + */ + public int getWidth(int i, int size) { + return size * width[i]; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidths() + */ + public int[] getWidths() { + int[] arr = new int[width.length]; + System.arraycopy(width, 0, arr, 0, width.length - 1); + /* + for (int i = 0; i < arr.length; i++) + arr[i] *= size; + */ + return arr; + } + + /** + * @see org.apache.fop.fonts.Font#mapChar(char) + */ + public char mapChar(char c) { + char d = mapping.mapChar(c); + if (d != 0) { + return d; + } else { + return '#'; + } + } + + /* ---- single byte font specific setters --- */ + + /** + * Sets a width for a character. + * @param index index of the character + * @param width the width of the character + */ + public void setWidth(int index, int width) { + if (this.width == null) { + this.width = new int[256]; + } + this.width[index] = width; + } + +} + diff --git a/src/java/org/apache/fop/fonts/apps/PFMReader.java b/src/java/org/apache/fop/fonts/apps/PFMReader.java new file mode 100644 index 000000000..66912068c --- /dev/null +++ b/src/java/org/apache/fop/fonts/apps/PFMReader.java @@ -0,0 +1,421 @@ +/* + * $Id: PFMReader.java,v 1.12 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.apps; + +import java.io.File; +import java.io.InputStream; +import java.io.IOException; +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +//Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.logger.ConsoleLogger; + +//FOP +import org.apache.fop.fonts.type1.PFMFile; + +/** + * A tool which reads PFM files from Adobe Type 1 fonts and creates + * XML font metrics file for use in FOP. + */ +public class PFMReader extends AbstractLogEnabled { + + /** + * Parse commandline arguments. put options in the HashMap and return + * arguments in the String array + * the arguments: -fn Perpetua,Bold -cn PerpetuaBold per.ttf Perpetua.xml + * returns a String[] with the per.ttf and Perpetua.xml. The hash + * will have the (key, value) pairs: (-fn, Perpetua) and (-cn, PerpetuaBold) + */ + private static String[] parseArguments(Map options, String[] args) { + List arguments = new java.util.ArrayList(); + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { + options.put(args[i], args[i + 1]); + i++; + } else { + options.put(args[i], ""); + } + } else { + arguments.add(args[i]); + } + } + + return (String[])arguments.toArray(new String[arguments.size()]); + } + + private void displayUsage() { + getLogger().info( + " java org.apache.fop.fonts.apps.PFMReader [options] metricfile.pfm xmlfile.xml"); + getLogger().info(" where options can be:"); + getLogger().info(" -fn "); + getLogger().info(" default is to use the fontname in the .pfm file, but"); + getLogger().info(" you can override that name to make sure that the"); + getLogger().info(" embedded font is used (if you're embedding fonts)"); + getLogger().info(" instead of installed fonts when viewing documents "); + getLogger().info(" with Acrobat Reader."); + } + + + /** + * The main method for the PFM reader tool. + * + * @param args Command-line arguments: [options] metricfile.pfm xmlfile.xml + * where options can be: + * -fn + * default is to use the fontname in the .pfm file, but you can override + * that name to make sure that the embedded font is used instead of installed + * fonts when viewing documents with Acrobat Reader. + * -cn + * default is to use the fontname + * -ef + * will add the possibility to embed the font. When running fop, fop will look + * for this file to embed it + * -er + * you can also include the fontfile in the fop.jar file when building fop. + * You can use both -ef and -er. The file specified in -ef will be searched first, + * then the -er file. + */ + public static void main(String[] args) { + String embFile = null; + String embResource = null; + String className = null; + String fontName = null; + + Map options = new java.util.HashMap(); + String[] arguments = parseArguments(options, args); + + PFMReader app = new PFMReader(); + Logger log; + if (options.get("-d") != null) { + log = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG); + } else { + log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); + } + app.enableLogging(log); + + log.info("PFM Reader v1.1a"); + log.info(""); + + if (options.get("-ef") != null) { + embFile = (String)options.get("-ef"); + } + + if (options.get("-er") != null) { + embResource = (String)options.get("-er"); + } + + if (options.get("-fn") != null) { + fontName = (String)options.get("-fn"); + } + + if (options.get("-cn") != null) { + className = (String)options.get("-cn"); + } + + if (arguments.length != 2 || options.get("-h") != null + || options.get("-help") != null || options.get("--help") != null) { + app.displayUsage(); + } else { + try { + PFMFile pfm = app.loadPFM(arguments[0]); + if (pfm != null) { + app.preview(pfm); + + Document doc = app.constructFontXML(pfm, + fontName, className, embResource, embFile); + + app.writeFontXML(doc, arguments[1]); + } + } catch (Exception e) { + log.error("Error while building XML font metrics file", e); + System.exit(-1); + } + } + } + + + /** + * Read a PFM file and returns it as an object. + * + * @param filename The filename of the PFM file. + * @return The PFM as an object. + * @throws IOException In case of an I/O problem + */ + public PFMFile loadPFM(String filename) throws IOException { + getLogger().info("Reading " + filename + "..."); + getLogger().info(""); + InputStream in = new java.io.FileInputStream(filename); + try { + PFMFile pfm = new PFMFile(); + setupLogger(pfm); + pfm.load(in); + return pfm; + } finally { + in.close(); + } + } + + /** + * Displays a preview of the PFM file on the console. + * + * @param pfm The PFM file to preview. + */ + public void preview(PFMFile pfm) { + getLogger().info("Font: " + pfm.getWindowsName()); + getLogger().info("Name: " + pfm.getPostscriptName()); + getLogger().info("CharSet: " + pfm.getCharSetName()); + getLogger().info("CapHeight: " + pfm.getCapHeight()); + getLogger().info("XHeight: " + pfm.getXHeight()); + getLogger().info("LowerCaseAscent: " + pfm.getLowerCaseAscent()); + getLogger().info("LowerCaseDescent: " + pfm.getLowerCaseDescent()); + getLogger().info("Having widths for " + (pfm.getLastChar() - pfm.getFirstChar()) + + " characters (" + pfm.getFirstChar() + + "-" + pfm.getLastChar() + ")."); + getLogger().info("for example: Char " + pfm.getFirstChar() + + " has a width of " + pfm.getCharWidth(pfm.getFirstChar())); + getLogger().info(""); + } + + /** + * Writes the generated DOM Document to a file. + * + * @param doc The DOM Document to save. + * @param target The target filename for the XML file. + * @throws TransformerException if an error occurs during serialization + */ + public void writeFontXML(org.w3c.dom.Document doc, String target) + throws TransformerException { + getLogger().info("Writing xml font file " + target + "..."); + getLogger().info(""); + + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.transform( + new javax.xml.transform.dom.DOMSource(doc), + new javax.xml.transform.stream.StreamResult(new File(target))); + } + + /** + * Generates the font metrics file from the PFM file. + * + * @param pfm The PFM file to generate the font metrics from. + * @param fontName name of the font + * @param className class name for the font + * @param resource path to the font as embedded resource + * @param file path to the font as file + * @return The DOM document representing the font metrics file. + */ + public org.w3c.dom.Document constructFontXML(PFMFile pfm, + String fontName, String className, String resource, String file) { + getLogger().info("Creating xml font file..."); + getLogger().info(""); + + Document doc; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + doc = factory.newDocumentBuilder().newDocument(); + } catch (javax.xml.parsers.ParserConfigurationException e) { + getLogger().error("Can't create DOM implementation", e); + return null; + } + Element root = doc.createElement("font-metrics"); + doc.appendChild(root); + root.setAttribute("type", "TYPE1"); + + Element el = doc.createElement("font-name"); + root.appendChild(el); + el.appendChild(doc.createTextNode(pfm.getPostscriptName())); + + String s = pfm.getPostscriptName(); + int pos = s.indexOf("-"); + if (pos >= 0) { + char sb[] = new char[s.length() - 1]; + s.getChars(0, pos, sb, 0); + s.getChars(pos + 1, s.length(), sb, pos); + s = new String(sb); + } + + el = doc.createElement("embed"); + root.appendChild(el); + if (file != null) { + el.setAttribute("file", file); + } + if (resource != null) { + el.setAttribute("class", resource); + } + + el = doc.createElement("encoding"); + root.appendChild(el); + el.appendChild(doc.createTextNode(pfm.getCharSetName() + "Encoding")); + + el = doc.createElement("cap-height"); + root.appendChild(el); + Integer value = new Integer(pfm.getCapHeight()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("x-height"); + root.appendChild(el); + value = new Integer(pfm.getXHeight()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("ascender"); + root.appendChild(el); + value = new Integer(pfm.getLowerCaseAscent()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("descender"); + root.appendChild(el); + value = new Integer(-pfm.getLowerCaseDescent()); + el.appendChild(doc.createTextNode(value.toString())); + + Element bbox = doc.createElement("bbox"); + root.appendChild(bbox); + int[] bb = pfm.getFontBBox(); + final String[] names = {"left", "bottom", "right", "top"}; + for (int i = 0; i < names.length; i++) { + el = doc.createElement(names[i]); + bbox.appendChild(el); + value = new Integer(bb[i]); + el.appendChild(doc.createTextNode(value.toString())); + } + + el = doc.createElement("flags"); + root.appendChild(el); + value = new Integer(pfm.getFlags()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("stemv"); + root.appendChild(el); + value = new Integer(pfm.getStemV()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("italicangle"); + root.appendChild(el); + value = new Integer(pfm.getItalicAngle()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("first-char"); + root.appendChild(el); + value = new Integer(pfm.getFirstChar()); + el.appendChild(doc.createTextNode(value.toString())); + + el = doc.createElement("last-char"); + root.appendChild(el); + value = new Integer(pfm.getLastChar()); + el.appendChild(doc.createTextNode(value.toString())); + + Element widths = doc.createElement("widths"); + root.appendChild(widths); + + for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) { + el = doc.createElement("char"); + widths.appendChild(el); + el.setAttribute("idx", Integer.toString(i)); + el.setAttribute("wdt", + new Integer(pfm.getCharWidth(i)).toString()); + } + + + // Get kerning + Iterator enum = pfm.getKerning().keySet().iterator(); + while (enum.hasNext()) { + Integer kpx1 = (Integer)enum.next(); + el = doc.createElement("kerning"); + el.setAttribute("kpx1", kpx1.toString()); + root.appendChild(el); + Element el2 = null; + + Map h2 = (Map)pfm.getKerning().get(kpx1); + Iterator enum2 = h2.keySet().iterator(); + while (enum2.hasNext()) { + Integer kpx2 = (Integer)enum2.next(); + el2 = doc.createElement("pair"); + el2.setAttribute("kpx2", kpx2.toString()); + Integer val = (Integer)h2.get(kpx2); + el2.setAttribute("kern", val.toString()); + el.appendChild(el2); + } + } + return doc; + } + + + private String escapeString(String str) { + StringBuffer esc = new StringBuffer(); + + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\\') { + esc.append("\\\\"); + } else { + esc.append(str.charAt(i)); + } + } + + return esc.toString(); + } + +} + + + + diff --git a/src/java/org/apache/fop/fonts/apps/TTFReader.java b/src/java/org/apache/fop/fonts/apps/TTFReader.java new file mode 100644 index 000000000..363f57e8d --- /dev/null +++ b/src/java/org/apache/fop/fonts/apps/TTFReader.java @@ -0,0 +1,544 @@ +/* + * $Id: TTFReader.java,v 1.13 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.apps; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.List; +import java.util.Iterator; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +//Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; + +//FOP +import org.apache.fop.fonts.truetype.FontFileReader; +import org.apache.fop.fonts.truetype.TTFCmapEntry; +import org.apache.fop.fonts.truetype.TTFFile; + +/** + * A tool which reads TTF files and generates + * XML font metrics file for use in FOP. + */ +public class TTFReader extends AbstractLogEnabled { + + /** + * Parse commandline arguments. put options in the HashMap and return + * arguments in the String array + * the arguments: -fn Perpetua,Bold -cn PerpetuaBold per.ttf Perpetua.xml + * returns a String[] with the per.ttf and Perpetua.xml. The hash + * will have the (key, value) pairs: (-fn, Perpetua) and (-cn, PerpetuaBold) + */ + private static String[] parseArguments(Map options, String[] args) { + List arguments = new java.util.ArrayList(); + for (int i = 0; i < args.length; i++) { + if (args[i].startsWith("-")) { + if ((i + 1) < args.length && !args[i + 1].startsWith("-")) { + options.put(args[i], args[i + 1]); + i++; + } else { + options.put(args[i], ""); + } + } else { + arguments.add(args[i]); + } + } + + return (String[])arguments.toArray(new String[0]); + } + + + private void displayUsage() { + getLogger().info( + " java org.apache.fop.fonts.apps.TTFReader [options] fontfile.ttf xmlfile.xml"); + getLogger().info(" where options can be:"); + getLogger().info("-enc ansi"); + getLogger().info(" With this option you create a WinAnsi encoded font."); + getLogger().info(" The default is to create a CID keyed font."); + getLogger().info(" If you're not going to use characters outside the"); + getLogger().info(" pdfencoding range (almost the same as iso-8889-1)"); + getLogger().info(" you can add this option."); + getLogger().info("-ttcname "); + getLogger().info(" If you're reading data from a TrueType Collection"); + getLogger().info(" (.ttc file) you must specify which font from the"); + getLogger().info(" collection you will read metrics from. If you read"); + getLogger().info(" from a .ttc file without this option, the fontnames"); + getLogger().info(" will be listed for you."); + getLogger().info(" -fn "); + getLogger().info(" default is to use the fontname in the .ttf file, but"); + getLogger().info(" you can override that name to make sure that the"); + getLogger().info(" embedded font is used (if you're embedding fonts)"); + getLogger().info(" instead of installed fonts when viewing documents "); + getLogger().info(" with Acrobat Reader."); + } + + + /** + * The main method for the TTFReader tool. + * + * @param args Command-line arguments: [options] fontfile.ttf xmlfile.xml + * where options can be: + * -fn + * default is to use the fontname in the .ttf file, but you can override + * that name to make sure that the embedded font is used instead of installed + * fonts when viewing documents with Acrobat Reader. + * -cn + * default is to use the fontname + * -ef + * will add the possibility to embed the font. When running fop, fop will look + * for this file to embed it + * -er + * you can also include the fontfile in the fop.jar file when building fop. + * You can use both -ef and -er. The file specified in -ef will be searched first, + * then the -er file. + */ + public static void main(String[] args) { + String embFile = null; + String embResource = null; + String className = null; + String fontName = null; + String ttcName = null; + boolean isCid = true; + + Map options = new java.util.HashMap(); + String[] arguments = parseArguments(options, args); + + int level = ConsoleLogger.LEVEL_INFO; + if (options.get("-d") != null) { + String lev = (String)options.get("-d"); + if (lev.equals("DEBUG")) { + level = ConsoleLogger.LEVEL_DEBUG; + } else if (lev.equals("INFO")) { + level = ConsoleLogger.LEVEL_INFO; + } + } + Logger log = new ConsoleLogger(level); + + TTFReader app = new TTFReader(); + app.enableLogging(log); + + log.info("TTF Reader v1.1.4"); + + if (options.get("-enc") != null) { + String enc = (String)options.get("-enc"); + if ("ansi".equals(enc)) { + isCid = false; + } + } + + if (options.get("-ttcname") != null) { + ttcName = (String)options.get("-ttcname"); + } + + if (options.get("-ef") != null) { + embFile = (String)options.get("-ef"); + } + + if (options.get("-er") != null) { + embResource = (String)options.get("-er"); + } + + if (options.get("-fn") != null) { + fontName = (String)options.get("-fn"); + } + + if (options.get("-cn") != null) { + className = (String)options.get("-cn"); + } + + if (arguments.length != 2 || options.get("-h") != null + || options.get("-help") != null || options.get("--help") != null) { + app.displayUsage(); + } else { + try { + TTFFile ttf = app.loadTTF(arguments[0], ttcName); + if (ttf != null) { + org.w3c.dom.Document doc = app.constructFontXML(ttf, + fontName, className, embResource, embFile, isCid, + ttcName); + + if (isCid) { + log.info("Creating CID encoded metrics"); + } else { + log.info("Creating WinAnsi encoded metrics"); + } + + if (doc != null) { + app.writeFontXML(doc, arguments[1]); + } + + if (ttf.isEmbeddable()) { + log.info("This font contains no embedding license restrictions"); + } else { + log.info("** Note: This font contains license retrictions for\n" + + " embedding. This font shouldn't be embedded."); + } + } + } catch (Exception e) { + log.error("Error while building XML font metrics file", e); + System.exit(-1); + } + } + } + + /** + * Read a TTF file and returns it as an object. + * + * @param fileName The filename of the TTF file. + * @param fontName The name of the font + * @return The TTF as an object, null if the font is incompatible. + * @throws IOException In case of an I/O problem + */ + public TTFFile loadTTF(String fileName, String fontName) throws IOException { + TTFFile ttfFile = new TTFFile(); + setupLogger(ttfFile); + getLogger().info("Reading " + fileName + "..."); + + FontFileReader reader = new FontFileReader(fileName); + boolean supported = ttfFile.readFont(reader, fontName); + if (!supported) { + return null; + } + return ttfFile; + } + + + /** + * Writes the generated DOM Document to a file. + * + * @param doc The DOM Document to save. + * @param target The target filename for the XML file. + * @throws TransformerException if an error occurs during serialization + */ + public void writeFontXML(org.w3c.dom.Document doc, String target) + throws TransformerException { + getLogger().info("Writing xml font file " + target + "..."); + + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.transform( + new javax.xml.transform.dom.DOMSource(doc), + new javax.xml.transform.stream.StreamResult(new File(target))); + } + + /** + * Generates the font metrics file from the TTF/TTC file. + * + * @param ttf The PFM file to generate the font metrics from. + * @param fontName Name of the font + * @param className Class name for the font + * @param resource path to the font as embedded resource + * @param file path to the font as file + * @param isCid True if the font is CID encoded + * @param ttcName Name of the TrueType Collection + * @return The DOM document representing the font metrics file. + */ + public org.w3c.dom.Document constructFontXML(TTFFile ttf, + String fontName, String className, String resource, String file, + boolean isCid, String ttcName) { + getLogger().info("Creating xml font file..."); + + Document doc; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + doc = factory.newDocumentBuilder().newDocument(); + } catch (javax.xml.parsers.ParserConfigurationException e) { + getLogger().error("Can't create DOM implementation", e); + return null; + } + Element root = doc.createElement("font-metrics"); + doc.appendChild(root); + if (isCid) { + root.setAttribute("type", "TYPE0"); + } else { + root.setAttribute("type", "TRUETYPE"); + } + + Element el = doc.createElement("font-name"); + root.appendChild(el); + + // Note that the PostScript name usually is something like + // "Perpetua-Bold", but the TrueType spec says that in the ttf file + // it should be "Perpetua,Bold". + + String s = stripWhiteSpace(ttf.getPostScriptName()); + + if (fontName != null) { + el.appendChild(doc.createTextNode(stripWhiteSpace(fontName))); + } else { + el.appendChild(doc.createTextNode(s)); + } + + el = doc.createElement("embed"); + root.appendChild(el); + if (file != null && ttf.isEmbeddable()) { + el.setAttribute("file", file); + } + if (resource != null && ttf.isEmbeddable()) { + el.setAttribute("class", resource); + } + + el = doc.createElement("cap-height"); + root.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getCapHeight()))); + + el = doc.createElement("x-height"); + root.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getXHeight()))); + + el = doc.createElement("ascender"); + root.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseAscent()))); + + el = doc.createElement("descender"); + root.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseDescent()))); + + Element bbox = doc.createElement("bbox"); + root.appendChild(bbox); + int[] bb = ttf.getFontBBox(); + final String[] names = {"left", "bottom", "right", "top"}; + for (int i = 0; i < names.length; i++) { + el = doc.createElement(names[i]); + bbox.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(bb[i]))); + } + + el = doc.createElement("flags"); + root.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getFlags()))); + + el = doc.createElement("stemv"); + root.appendChild(el); + el.appendChild(doc.createTextNode(ttf.getStemV())); + + el = doc.createElement("italicangle"); + root.appendChild(el); + el.appendChild(doc.createTextNode(ttf.getItalicAngle())); + + if (ttcName != null) { + el = doc.createElement("ttc-name"); + root.appendChild(el); + el.appendChild(doc.createTextNode(ttcName)); + } + + el = doc.createElement("subtype"); + root.appendChild(el); + + // Fill in extras for CID keyed fonts + if (isCid) { + el.appendChild(doc.createTextNode("TYPE0")); + + generateDOM4MultiByteExtras(root, ttf, isCid); + } else { + // Fill in extras for singlebyte fonts + el.appendChild(doc.createTextNode("TRUETYPE")); + + generateDOM4SingleByteExtras(root, ttf, isCid); + } + + generateDOM4Kerning(root, ttf, isCid); + + return doc; + } + + private void generateDOM4MultiByteExtras(Element parent, TTFFile ttf, boolean isCid) { + Element el; + Document doc = parent.getOwnerDocument(); + + Element mel = doc.createElement("multibyte-extras"); + parent.appendChild(mel); + + el = doc.createElement("cid-type"); + mel.appendChild(el); + el.appendChild(doc.createTextNode("CIDFontType2")); + + el = doc.createElement("default-width"); + mel.appendChild(el); + el.appendChild(doc.createTextNode("0")); + + el = doc.createElement("bfranges"); + mel.appendChild(el); + Iterator e = ttf.getCMaps().listIterator(); + while (e.hasNext()) { + TTFCmapEntry ce = (TTFCmapEntry)e.next(); + Element el2 = doc.createElement("bf"); + el.appendChild(el2); + el2.setAttribute("us", String.valueOf(ce.getUnicodeStart())); + el2.setAttribute("ue", String.valueOf(ce.getUnicodeEnd())); + el2.setAttribute("gi", String.valueOf(ce.getGlyphStartIndex())); + } + + el = doc.createElement("cid-widths"); + el.setAttribute("start-index", "0"); + mel.appendChild(el); + + int[] wx = ttf.getWidths(); + for (int i = 0; i < wx.length; i++) { + Element wxel = doc.createElement("wx"); + wxel.setAttribute("w", String.valueOf(wx[i])); + el.appendChild(wxel); + } + } + + private void generateDOM4SingleByteExtras(Element parent, TTFFile ttf, boolean isCid) { + Element el; + Document doc = parent.getOwnerDocument(); + + Element sel = doc.createElement("singlebyte-extras"); + parent.appendChild(sel); + + el = doc.createElement("encoding"); + sel.appendChild(el); + el.appendChild(doc.createTextNode(ttf.getCharSetName())); + + el = doc.createElement("first-char"); + sel.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getFirstChar()))); + + el = doc.createElement("last-char"); + sel.appendChild(el); + el.appendChild(doc.createTextNode(String.valueOf(ttf.getLastChar()))); + + Element widths = doc.createElement("widths"); + sel.appendChild(widths); + + for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); i++) { + el = doc.createElement("char"); + widths.appendChild(el); + el.setAttribute("idx", String.valueOf(i)); + el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i))); + } + } + + private void generateDOM4Kerning(Element parent, TTFFile ttf, boolean isCid) { + Element el; + Document doc = parent.getOwnerDocument(); + + // Get kerning + Iterator enum; + if (isCid) { + enum = ttf.getKerning().keySet().iterator(); + } else { + enum = ttf.getAnsiKerning().keySet().iterator(); + } + + while (enum.hasNext()) { + Integer kpx1 = (Integer)enum.next(); + + el = doc.createElement("kerning"); + el.setAttribute("kpx1", kpx1.toString()); + parent.appendChild(el); + Element el2 = null; + + Map h2; + if (isCid) { + h2 = (Map)ttf.getKerning().get(kpx1); + } else { + h2 = (Map)ttf.getAnsiKerning().get(kpx1); + } + + Iterator enum2 = h2.keySet().iterator(); + while (enum2.hasNext()) { + Integer kpx2 = (Integer)enum2.next(); + if (isCid || kpx2.intValue() < 256) { + el2 = doc.createElement("pair"); + el2.setAttribute("kpx2", kpx2.toString()); + Integer val = (Integer)h2.get(kpx2); + el2.setAttribute("kern", val.toString()); + el.appendChild(el2); + } + } + } + } + + + private String stripWhiteSpace(String s) { + char[] ch = new char[s.length()]; + s.getChars(0, s.length(), ch, 0); + StringBuffer stb = new StringBuffer(); + for (int i = 0; i < ch.length; i++) { + if (ch[i] != ' ' + && ch[i] != '\r' + && ch[i] != '\n' + && ch[i] != '\t') { + stb.append(ch[i]); + } + } + + return stb.toString(); + } + + private String escapeString(String str) { + StringBuffer esc = new StringBuffer(); + + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\\') { + esc.append("\\\\"); + } else { + esc.append(str.charAt(i)); + } + } + + return esc.toString(); + } + +} + diff --git a/src/java/org/apache/fop/fonts/base14/package.html b/src/java/org/apache/fop/fonts/base14/package.html new file mode 100644 index 000000000..90c58d555 --- /dev/null +++ b/src/java/org/apache/fop/fonts/base14/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.fonts.base14 Package + +

Base 14 fonts used for PDF and PostScript. Generated entirely from XML files.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/package.html b/src/java/org/apache/fop/fonts/package.html new file mode 100644 index 000000000..33e1e2cb3 --- /dev/null +++ b/src/java/org/apache/fop/fonts/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.fonts Package + +

Classes for font handling. Subpackages contain command line applications for font metrics generation, font parsing classes etc.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java new file mode 100644 index 000000000..1c098a875 --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java @@ -0,0 +1,367 @@ +/* + * $Id: FontFileReader.java,v 1.2 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +import java.io.InputStream; +import java.io.File; +import java.io.IOException; + +import org.apache.fop.util.StreamUtilities; + +/** + * Reads a TrueType font file into a byte array and + * provides file like functions for array access. + */ +public class FontFileReader { + + private int fsize; // file size + private int current; // current position in file + private byte[] file; + + /** + * Initializes class and reads stream. Init does not close stream. + * + * @param in InputStream to read from new array with size + inc + * @throws IOException In case of an I/O problem + */ + private void init(InputStream in) throws java.io.IOException { + java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream(); + try { + StreamUtilities.streamCopy(in, bout); + this.file = bout.toByteArray(); + this.fsize = this.file.length; + this.current = 0; + } finally { + bout.close(); + } + } + + /** + * Constructor + * + * @param fileName filename to read + * @throws IOException In case of an I/O problem + */ + public FontFileReader(String fileName) throws IOException { + final File f = new File(fileName); + InputStream in = new java.io.FileInputStream(f); + try { + init(in); + } finally { + in.close(); + } + } + + + /** + * Constructor + * + * @param in InputStream to read from + * @throws IOException In case of an I/O problem + */ + public FontFileReader(InputStream in) throws IOException { + init(in); + } + + + /** + * Set current file position to offset + * + * @param offset The new offset to set + * @throws IOException In case of an I/O problem + */ + public void seekSet(long offset) throws IOException { + if (offset > fsize || offset < 0) { + throw new java.io.EOFException("Reached EOF, file size=" + fsize + + " offset=" + offset); + } + current = (int)offset; + } + + /** + * Set current file position to offset + * + * @param add The number of bytes to advance + * @throws IOException In case of an I/O problem + */ + public void seekAdd(long add) throws IOException { + seekSet(current + add); + } + + /** + * Skip a given number of bytes. + * + * @param add The number of bytes to advance + * @throws IOException In case of an I/O problem + */ + public void skip(long add) throws IOException { + seekAdd(add); + } + + /** + * Returns current file position. + * + * @return int The current position. + */ + public int getCurrentPos() { + return current; + } + + /** + * Returns the size of the file. + * + * @return int The filesize + */ + public int getFileSize() { + return fsize; + } + + /** + * Read 1 byte. + * + * @return One byte + * @throws IOException If EOF is reached + */ + public byte read() throws IOException { + if (current > fsize) { + throw new java.io.EOFException("Reached EOF, file size=" + fsize); + } + + final byte ret = file[current++]; + return ret; + } + + /** + * Read 1 signed byte. + * + * @return One byte + * @throws IOException If EOF is reached + */ + public final byte readTTFByte() throws IOException { + return read(); + } + + /** + * Read 1 unsigned byte. + * + * @return One unsigned byte + * @throws IOException If EOF is reached + */ + public final int readTTFUByte() throws IOException { + final byte buf = read(); + + if (buf < 0) { + return (int)(256 + buf); + } else { + return (int)buf; + } + } + + /** + * Read 2 bytes signed. + * + * @return One signed short + * @throws IOException If EOF is reached + */ + public final short readTTFShort() throws IOException { + final int ret = (readTTFUByte() << 8) + readTTFUByte(); + final short sret = (short)ret; + return sret; + } + + /** + * Read 2 bytes unsigned. + * + * @return One unsigned short + * @throws IOException If EOF is reached + */ + public final int readTTFUShort() throws IOException { + final int ret = (readTTFUByte() << 8) + readTTFUByte(); + return (int)ret; + } + + /** + * Write a USHort at a given position. + * + * @param pos The absolute position to write to + * @param val The value to write + * @throws IOException If EOF is reached + */ + public final void writeTTFUShort(int pos, int val) throws IOException { + if ((pos + 2) > fsize) { + throw new java.io.EOFException("Reached EOF"); + } + final byte b1 = (byte)((val >> 8) & 0xff); + final byte b2 = (byte)(val & 0xff); + file[pos] = b1; + file[pos + 1] = b2; + } + + /** + * Read 2 bytes signed at position pos without changing current position. + * + * @param pos The absolute position to read from + * @return One signed short + * @throws IOException If EOF is reached + */ + public final short readTTFShort(long pos) throws IOException { + final long cp = getCurrentPos(); + seekSet(pos); + final short ret = readTTFShort(); + seekSet(cp); + return ret; + } + + /** + * Read 2 bytes unsigned at position pos without changing current position. + * + * @param pos The absolute position to read from + * @return One unsigned short + * @throws IOException If EOF is reached + */ + public final int readTTFUShort(long pos) throws IOException { + long cp = getCurrentPos(); + seekSet(pos); + int ret = readTTFUShort(); + seekSet(cp); + return ret; + } + + /** + * Read 4 bytes. + * + * @return One signed integer + * @throws IOException If EOF is reached + */ + public final int readTTFLong() throws IOException { + long ret = readTTFUByte(); // << 8; + ret = (ret << 8) + readTTFUByte(); + ret = (ret << 8) + readTTFUByte(); + ret = (ret << 8) + readTTFUByte(); + + return (int)ret; + } + + /** + * Read 4 bytes. + * + * @return One unsigned integer + * @throws IOException If EOF is reached + */ + public final long readTTFULong() throws IOException { + long ret = readTTFUByte(); + ret = (ret << 8) + readTTFUByte(); + ret = (ret << 8) + readTTFUByte(); + ret = (ret << 8) + readTTFUByte(); + + return ret; + } + + /** + * Read a NUL terminated ISO-8859-1 string. + * + * @return A String + * @throws IOException If EOF is reached + */ + public final String readTTFString() throws IOException { + int i = current; + while (file[i++] != 0) { + if (i > fsize) { + throw new java.io.EOFException("Reached EOF, file size=" + + fsize); + } + } + + byte[] tmp = new byte[i - current]; + System.arraycopy(file, current, tmp, 0, i - current); + return new String(tmp, "ISO-8859-1"); + } + + + /** + * Read an ISO-8859-1 string of len bytes. + * + * @param len The length of the string to read + * @return A String + * @throws IOException If EOF is reached + */ + public final String readTTFString(int len) throws IOException { + if ((len + current) > fsize) { + throw new java.io.EOFException("Reached EOF, file size=" + fsize); + } + + byte[] tmp = new byte[len]; + System.arraycopy(file, current, tmp, 0, len); + current += len; + return new String(tmp, "ISO-8859-1"); + } + + /** + * Return a copy of the internal array + * + * @param offset The absolute offset to start reading from + * @param length The number of bytes to read + * @return An array of bytes + * @throws IOException if out of bounds + */ + public byte[] getBytes(int offset, + int length) throws IOException { + if ((offset + length) > fsize) { + throw new java.io.IOException("Reached EOF"); + } + + byte[] ret = new byte[length]; + System.arraycopy(file, offset, ret, 0, length); + return ret; + } + + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java new file mode 100644 index 000000000..d7b243058 --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java @@ -0,0 +1,138 @@ +/* + * $Id: TTFCmapEntry.java,v 1.2 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +/** + * The CMap entry contains information of a Unicode range and the + * the glyph indexes related to the range + */ +public class TTFCmapEntry { + + private int unicodeStart; + private int unicodeEnd; + private int glyphStartIndex; + + TTFCmapEntry() { + unicodeStart = 0; + unicodeEnd = 0; + glyphStartIndex = 0; + } + + TTFCmapEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) { + this.unicodeStart = unicodeStart; + this.unicodeEnd = unicodeEnd; + this.glyphStartIndex = glyphStartIndex; + } + + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object o) { + if (o instanceof TTFCmapEntry) { + TTFCmapEntry ce = (TTFCmapEntry)o; + if (ce.unicodeStart == this.unicodeStart + && ce.unicodeEnd == this.unicodeEnd + && ce.glyphStartIndex == this.glyphStartIndex) { + return true; + } + } + return false; + } + + /** + * Returns the glyphStartIndex. + * @return int + */ + public int getGlyphStartIndex() { + return glyphStartIndex; + } + + /** + * Returns the unicodeEnd. + * @return int + */ + public int getUnicodeEnd() { + return unicodeEnd; + } + + /** + * Returns the unicodeStart. + * @return int + */ + public int getUnicodeStart() { + return unicodeStart; + } + + /** + * Sets the glyphStartIndex. + * @param glyphStartIndex The glyphStartIndex to set + */ + public void setGlyphStartIndex(int glyphStartIndex) { + this.glyphStartIndex = glyphStartIndex; + } + + /** + * Sets the unicodeEnd. + * @param unicodeEnd The unicodeEnd to set + */ + public void setUnicodeEnd(int unicodeEnd) { + this.unicodeEnd = unicodeEnd; + } + + /** + * Sets the unicodeStart. + * @param unicodeStart The unicodeStart to set + */ + public void setUnicodeStart(int unicodeStart) { + this.unicodeStart = unicodeStart; + } + +} diff --git a/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java new file mode 100644 index 000000000..6907cb27d --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java @@ -0,0 +1,125 @@ +/* + * $Id: TTFDirTabEntry.java,v 1.2 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +import java.io.IOException; + + +/** + * This class represents an entry to a TrueType font's Dir Tab. + */ +class TTFDirTabEntry { + + private byte[] tag = new byte[4]; + private int checksum; + private long offset; + private long length; + + /** + * Read Dir Tab, return tag name + */ + public String read(FontFileReader in) throws IOException { + tag[0] = in.readTTFByte(); + tag[1] = in.readTTFByte(); + tag[2] = in.readTTFByte(); + tag[3] = in.readTTFByte(); + + in.skip(4); // Skip checksum + + offset = in.readTTFULong(); + length = in.readTTFULong(); + + //System.out.println(this.toString()); + return new String(tag, "ISO-8859-1"); + } + + + public String toString() { + return "Read dir tab [" + + tag[0] + " " + tag[1] + " " + tag[2] + " " + tag[3] + "]" + + " offset: " + offset + + " length: " + length + + " name: " + tag; + } + + /** + * Returns the checksum. + * @return int + */ + public int getChecksum() { + return checksum; + } + + /** + * Returns the length. + * @return long + */ + public long getLength() { + return length; + } + + /** + * Returns the offset. + * @return long + */ + public long getOffset() { + return offset; + } + + /** + * Returns the tag. + * @return byte[] + */ + public byte[] getTag() { + return tag; + } + +} diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java new file mode 100644 index 000000000..e377088cd --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java @@ -0,0 +1,1327 @@ +/* + * $Id: TTFFile.java,v 1.4 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.List; + +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; +import org.apache.fop.fonts.Glyphs; + +/** + * Reads a TrueType file or a TrueType Collection. + * The TrueType spec can be found at the Microsoft. + * Typography site: http://www.microsoft.com/truetype/ + */ +public class TTFFile extends AbstractLogEnabled { + + static final byte NTABS = 24; + static final int NMACGLYPHS = 258; + static final int MAX_CHAR_CODE = 255; + static final int ENC_BUF_SIZE = 1024; + + private String encoding = "WinAnsiEncoding"; // Default encoding + + private short firstChar = 0; + private boolean isEmbeddable = true; + private boolean hasSerifs = true; + /** + * Table directory + */ + protected Map dirTabs; + private Map kerningTab; // for CIDs + private Map ansiKerningTab; // For winAnsiEncoding + private List cmaps; + private List unicodeMapping; + + private int upem; // unitsPerEm from "head" table + private int nhmtx; // Number of horizontal metrics + private int postFormat; + private int locaFormat; + /** + * Offset to last loca + */ + protected long lastLoca = 0; + private int numberOfGlyphs; // Number of glyphs in font (read from "maxp" table) + private int nmGlyphs; // Used in fixWidths - remove? + + /** + * Contains glyph data + */ + protected TTFMtxEntry mtxTab[]; // Contains glyph data + private int[] mtxEncoded = null; + + private String fontName = ""; + private String fullName = ""; + private String notice = ""; + private String familyName = ""; + private String subFamilyName = ""; + + private long italicAngle = 0; + private long isFixedPitch = 0; + private int fontBBox1 = 0; + private int fontBBox2 = 0; + private int fontBBox3 = 0; + private int fontBBox4 = 0; + private int capHeight = 0; + private int underlinePosition = 0; + private int underlineThickness = 0; + private int xHeight = 0; + private int ascender = 0; + private int descender = 0; + + private short lastChar = 0; + + private int ansiWidth[]; + private Map ansiIndex; + + private TTFDirTabEntry currentDirTab; + + /** + * Position inputstream to position indicated + * in the dirtab offset + offset + */ + void seekTab(FontFileReader in, String name, + long offset) throws IOException { + TTFDirTabEntry dt = (TTFDirTabEntry)dirTabs.get(name); + if (dt == null) { + getLogger().error("Dirtab " + name + " not found."); + } else { + in.seekSet(dt.getOffset() + offset); + this.currentDirTab = dt; + } + } + + /** + * Convert from truetype unit to pdf unit based on the + * unitsPerEm field in the "head" table + * @param n truetype unit + * @return pdf unit + */ + public int convertTTFUnit2PDFUnit(int n) { + int ret; + if (n < 0) { + long rest1 = n % upem; + long storrest = 1000 * rest1; + long ledd2 = rest1 / storrest; + ret = -((-1000 * n) / upem - (int)ledd2); + } else { + ret = (n / upem) * 1000 + ((n % upem) * 1000) / upem; + } + + return ret; + } + + /** + * Read the cmap table, + * return false if the table is not present or only unsupported + * tables are present. Currently only unicode cmaps are supported. + * Set the unicodeIndex in the TTFMtxEntries and fills in the + * cmaps vector. + */ + private boolean readCMAP(FontFileReader in) throws IOException { + + unicodeMapping = new java.util.ArrayList(); + + //Read CMAP table and correct mtxTab.index + int mtxPtr = 0; + + seekTab(in, "cmap", 2); + int numCMap = in.readTTFUShort(); // Number of cmap subtables + long cmapUniOffset = 0; + + getLogger().info(numCMap + " cmap tables"); + + //Read offset for all tables. We are only interested in the unicode table + for (int i = 0; i < numCMap; i++) { + int cmapPID = in.readTTFUShort(); + int cmapEID = in.readTTFUShort(); + long cmapOffset = in.readTTFULong(); + + getLogger().debug("Platform ID: " + cmapPID + + " Encoding: " + cmapEID); + + if (cmapPID == 3 && cmapEID == 1) { + cmapUniOffset = cmapOffset; + } + } + + if (cmapUniOffset <= 0) { + getLogger().fatalError("Unicode cmap table not present"); + getLogger().fatalError("Unsupported format: Aborting"); + return false; + } + + // Read unicode cmap + seekTab(in, "cmap", cmapUniOffset); + int cmapFormat = in.readTTFUShort(); + /*int cmap_length =*/ in.readTTFUShort(); //skip cmap length + + getLogger().info("CMAP format: " + cmapFormat); + if (cmapFormat == 4) { + in.skip(2); // Skip version number + int cmapSegCountX2 = in.readTTFUShort(); + int cmapSearchRange = in.readTTFUShort(); + int cmapEntrySelector = in.readTTFUShort(); + int cmapRangeShift = in.readTTFUShort(); + + if (getLogger().isDebugEnabled()) { + getLogger().debug("segCountX2 : " + cmapSegCountX2); + getLogger().debug("searchRange : " + cmapSearchRange); + getLogger().debug("entrySelector: " + cmapEntrySelector); + getLogger().debug("rangeShift : " + cmapRangeShift); + } + + + int cmapEndCounts[] = new int[cmapSegCountX2 / 2]; + int cmapStartCounts[] = new int[cmapSegCountX2 / 2]; + int cmapDeltas[] = new int[cmapSegCountX2 / 2]; + int cmapRangeOffsets[] = new int[cmapSegCountX2 / 2]; + + for (int i = 0; i < (cmapSegCountX2 / 2); i++) { + cmapEndCounts[i] = in.readTTFUShort(); + } + + in.skip(2); // Skip reservedPad + + for (int i = 0; i < (cmapSegCountX2 / 2); i++) { + cmapStartCounts[i] = in.readTTFUShort(); + } + + for (int i = 0; i < (cmapSegCountX2 / 2); i++) { + cmapDeltas[i] = in.readTTFShort(); + } + + //int startRangeOffset = in.getCurrentPos(); + + for (int i = 0; i < (cmapSegCountX2 / 2); i++) { + cmapRangeOffsets[i] = in.readTTFUShort(); + } + + int glyphIdArrayOffset = in.getCurrentPos(); + + // Insert the unicode id for the glyphs in mtxTab + // and fill in the cmaps ArrayList + + for (int i = 0; i < cmapStartCounts.length; i++) { + + getLogger().debug(i + ": " + cmapStartCounts[i] + + " - " + cmapEndCounts[i]); + + for (int j = cmapStartCounts[i]; j <= cmapEndCounts[i]; j++) { + + // Update lastChar + if (j < 256 && j > lastChar) { + lastChar = (short)j; + } + + if (mtxPtr < mtxTab.length) { + int glyphIdx; + // the last character 65535 = .notdef + // may have a range offset + if (cmapRangeOffsets[i] != 0 && j != 65535) { + int glyphOffset = glyphIdArrayOffset + + ((cmapRangeOffsets[i] / 2) + + (j - cmapStartCounts[i]) + + (i) + - cmapSegCountX2 / 2) * 2; + in.seekSet(glyphOffset); + glyphIdx = (in.readTTFUShort() + cmapDeltas[i]) + & 0xffff; + + unicodeMapping.add(new UnicodeMapping(glyphIdx, j)); + mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j)); + + + // Also add winAnsiWidth + List v = (List)ansiIndex.get(new Integer(j)); + if (v != null) { + Iterator e = v.listIterator(); + while (e.hasNext()) { + Integer aIdx = (Integer)e.next(); + ansiWidth[aIdx.intValue()] = + mtxTab[glyphIdx].getWx(); + + if (getLogger().isDebugEnabled()) { + getLogger().debug("Added width " + + mtxTab[glyphIdx].getWx() + + " uni: " + j + + " ansi: " + aIdx.intValue()); + } + } + } + + if (getLogger().isDebugEnabled()) { + getLogger().debug("Idx: " + + glyphIdx + + " Delta: " + cmapDeltas[i] + + " Unicode: " + j + + " name: " + mtxTab[glyphIdx].getName()); + } + } else { + glyphIdx = (j + cmapDeltas[i]) & 0xffff; + + if (glyphIdx < mtxTab.length) { + mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j)); + } else { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Glyph " + glyphIdx + + " out of range: " + + mtxTab.length); + } + } + + unicodeMapping.add(new UnicodeMapping(glyphIdx, j)); + if (glyphIdx < mtxTab.length) { + mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j)); + } else { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Glyph " + glyphIdx + + " out of range: " + + mtxTab.length); + } + } + + // Also add winAnsiWidth + List v = (List)ansiIndex.get(new Integer(j)); + if (v != null) { + Iterator e = v.listIterator(); + while (e.hasNext()) { + Integer aIdx = (Integer)e.next(); + ansiWidth[aIdx.intValue()] = mtxTab[glyphIdx].getWx(); + } + } + + //getLogger().debug("IIdx: " + + // mtxPtr + + // " Delta: " + cmap_deltas[i] + + // " Unicode: " + j + + // " name: " + + // mtxTab[(j+cmap_deltas[i]) & 0xffff].name); + + } + if (glyphIdx < mtxTab.length) { + if (mtxTab[glyphIdx].getUnicodeIndex().size() < 2) { + mtxPtr++; + } + } + } + } + } + } + return true; + } + + /** + * Print first char/last char + */ + private void printMaxMin() { + int min = 255; + int max = 0; + for (int i = 0; i < mtxTab.length; i++) { + if (mtxTab[i].getIndex() < min) { + min = mtxTab[i].getIndex(); + } + if (mtxTab[i].getIndex() > max) { + max = mtxTab[i].getIndex(); + } + } + getLogger().info("Min: " + min); + getLogger().info("Max: " + max); + } + + + /** + * Reads the font using a FontFileReader. + * + * @param in The FontFileReader to use + * @throws IOException In case of an I/O problem + */ + public void readFont(FontFileReader in) throws IOException { + readFont(in, (String)null); + } + + /** + * initialize the ansiWidths array (for winAnsiEncoding) + * and fill with the missingwidth + */ + private void initAnsiWidths() { + ansiWidth = new int[256]; + for (int i = 0; i < 256; i++) { + ansiWidth[i] = mtxTab[0].getWx(); + } + + // Create an index hash to the ansiWidth + // Can't just index the winAnsiEncoding when inserting widths + // same char (eg bullet) is repeated more than one place + ansiIndex = new java.util.HashMap(); + for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) { + Integer ansi = new Integer(i); + Integer uni = new Integer((int)Glyphs.WINANSI_ENCODING[i]); + + List v = (List)ansiIndex.get(uni); + if (v == null) { + v = new java.util.ArrayList(); + ansiIndex.put(uni, v); + } + v.add(ansi); + } + } + + /** + * Read the font data. + * If the fontfile is a TrueType Collection (.ttc file) + * the name of the font to read data for must be supplied, + * else the name is ignored. + * + * @param in The FontFileReader to use + * @param name The name of the font + * @return boolean Returns true if the font is valid + * @throws IOException In case of an I/O problem + */ + public boolean readFont(FontFileReader in, String name) throws IOException { + + /* + * Check if TrueType collection, and that the name + * exists in the collection + */ + if (!checkTTC(in, name)) { + throw new IOException("Failed to read font"); + } + + readDirTabs(in); + readFontHeader(in); + getNumGlyphs(in); + getLogger().info("Number of glyphs in font: " + numberOfGlyphs); + readHorizontalHeader(in); + readHorizontalMetrics(in); + initAnsiWidths(); + readPostScript(in); + readOS2(in); + readIndexToLocation(in); + readGlyf(in); + readName(in); + readPCLT(in); + // Read cmap table and fill in ansiwidths + boolean valid = readCMAP(in); + if (!valid) { + return false; + } + // Create cmaps for bfentries + createCMaps(); + // print_max_min(); + + readKerning(in); + return true; + } + + private void createCMaps() { + cmaps = new java.util.ArrayList(); + TTFCmapEntry tce = new TTFCmapEntry(); + + Iterator e = unicodeMapping.listIterator(); + UnicodeMapping um = (UnicodeMapping)e.next(); + UnicodeMapping lastMapping = um; + + tce.setUnicodeStart(um.getUIdx()); + tce.setGlyphStartIndex(um.getGIdx()); + + while (e.hasNext()) { + um = (UnicodeMapping)e.next(); + if (((lastMapping.getUIdx() + 1) != um.getUIdx()) + || ((lastMapping.getGIdx() + 1) != um.getGIdx())) { + tce.setUnicodeEnd(lastMapping.getUIdx()); + cmaps.add(tce); + + tce = new TTFCmapEntry(); + tce.setUnicodeStart(um.getUIdx()); + tce.setGlyphStartIndex(um.getGIdx()); + } + lastMapping = um; + } + + tce.setUnicodeEnd(um.getUIdx()); + cmaps.add(tce); + } + + /** + * Returns the Windows name of the font. + * @return String The Windows name + */ + public String getWindowsName() { + return familyName + "," + subFamilyName; + } + + /** + * Returns the PostScript name of the font. + * @return String The PostScript name + */ + public String getPostScriptName() { + if ("Regular".equals(subFamilyName) || "Roman".equals(subFamilyName)) { + return familyName; + } else { + return familyName + "," + subFamilyName; + } + } + + /** + * Returns the font family name of the font. + * @return String The family name + */ + public String getFamilyName() { + return familyName; + } + + /** + * Returns the name of the character set used. + * @return String The caracter set + */ + public String getCharSetName() { + return encoding; + } + + /** + * Returns the CapHeight attribute of the font. + * @return int The CapHeight + */ + public int getCapHeight() { + return (int)convertTTFUnit2PDFUnit(capHeight); + } + + /** + * Returns the XHeight attribute of the font. + * @return int The XHeight + */ + public int getXHeight() { + return (int)convertTTFUnit2PDFUnit(xHeight); + } + + /** + * Returns the Flags attribute of the font. + * @return int The Flags + */ + public int getFlags() { + int flags = 32; // Use Adobe Standard charset + if (italicAngle != 0) { + flags = flags | 64; + } + if (isFixedPitch != 0) { + flags = flags | 2; + } + if (hasSerifs) { + flags = flags | 1; + } + return flags; + } + + + /** + * Returns the StemV attribute of the font. + * @return String The StemV + */ + public String getStemV() { + return "0"; + } + + /** + * Returns the ItalicAngle attribute of the font. + * @return String The ItalicAngle + */ + public String getItalicAngle() { + String ia = Short.toString((short)(italicAngle / 0x10000)); + + // This is the correct italic angle, however only int italic + // angles are supported at the moment so this is commented out. + /* + * if ((italicAngle % 0x10000) > 0 ) + * ia=ia+(comma+Short.toString((short)((short)((italicAngle % 0x10000)*1000)/0x10000))); + */ + return ia; + } + + /** + * Returns the font bounding box. + * @return int[] The font bbox + */ + public int[] getFontBBox() { + final int[] fbb = new int[4]; + fbb[0] = (int)convertTTFUnit2PDFUnit(fontBBox1); + fbb[1] = (int)convertTTFUnit2PDFUnit(fontBBox2); + fbb[2] = (int)convertTTFUnit2PDFUnit(fontBBox3); + fbb[3] = (int)convertTTFUnit2PDFUnit(fontBBox4); + + return fbb; + } + + /** + * Returns the LowerCaseAscent attribute of the font. + * @return int The LowerCaseAscent + */ + public int getLowerCaseAscent() { + return (int)convertTTFUnit2PDFUnit(ascender); + } + + /** + * Returns the LowerCaseDescent attribute of the font. + * @return int The LowerCaseDescent + */ + public int getLowerCaseDescent() { + return (int)convertTTFUnit2PDFUnit(descender); + } + + /** + * Returns the index of the last character, but this is for WinAnsiEncoding + * only, so the last char is < 256. + * @return short Index of the last character (<256) + */ + public short getLastChar() { + return lastChar; + } + + /** + * Returns the index of the first character. + * @return short Index of the first character + */ + public short getFirstChar() { + return firstChar; + } + + /** + * Returns an array of character widths. + * @return int[] The character widths + */ + public int[] getWidths() { + int[] wx = new int[mtxTab.length]; + for (int i = 0; i < wx.length; i++) { + wx[i] = (int)convertTTFUnit2PDFUnit(mtxTab[i].getWx()); + } + + return wx; + } + + /** + * Returns the width of a given character. + * @param idx Index of the character + * @return int Standard width + */ + public int getCharWidth(int idx) { + return (int)convertTTFUnit2PDFUnit(ansiWidth[idx]); + } + + /** + * Returns the kerning table. + * @return Map The kerning table + */ + public Map getKerning() { + return kerningTab; + } + + /** + * Returns the ANSI kerning table. + * @return Map The ANSI kerning table + */ + public Map getAnsiKerning() { + return ansiKerningTab; + } + + /** + * Indicates if the font may be embedded. + * @return boolean True if it may be embedded + */ + public boolean isEmbeddable() { + return isEmbeddable; + } + + + /** + * Read Table Directory from the current position in the + * FontFileReader and fill the global HashMap dirTabs + * with the table name (String) as key and a TTFDirTabEntry + * as value. + * @param in FontFileReader to read the table directory from + * @throws IOException in case of an I/O problem + */ + protected void readDirTabs(FontFileReader in) throws IOException { + in.skip(4); // TTF_FIXED_SIZE + int ntabs = in.readTTFUShort(); + in.skip(6); // 3xTTF_USHORT_SIZE + + dirTabs = new java.util.HashMap(); + TTFDirTabEntry[] pd = new TTFDirTabEntry[ntabs]; + getLogger().debug("Reading " + ntabs + " dir tables"); + for (int i = 0; i < ntabs; i++) { + pd[i] = new TTFDirTabEntry(); + dirTabs.put(pd[i].read(in), pd[i]); + } + } + + /** + * Read the "head" table, this reads the bounding box and + * sets the upem (unitsPerEM) variable + * @param in FontFileReader to read the header from + * @throws IOException in case of an I/O problem + */ + protected void readFontHeader(FontFileReader in) throws IOException { + seekTab(in, "head", 2 * 4 + 2 * 4 + 2); + upem = in.readTTFUShort(); + + in.skip(16); + + fontBBox1 = in.readTTFShort(); + fontBBox2 = in.readTTFShort(); + fontBBox3 = in.readTTFShort(); + fontBBox4 = in.readTTFShort(); + + in.skip(2 + 2 + 2); + + locaFormat = in.readTTFShort(); + } + + /** + * Read the number of glyphs from the "maxp" table + * @param in FontFileReader to read the number of glyphs from + * @throws IOException in case of an I/O problem + */ + protected void getNumGlyphs(FontFileReader in) throws IOException { + seekTab(in, "maxp", 4); + numberOfGlyphs = in.readTTFUShort(); + } + + + /** + * Read the "hhea" table to find the ascender and descender and + * size of "hmtx" table, i.e. a fixed size font might have only + * one width + * @param in FontFileReader to read the hhea table from + * @throws IOException in case of an I/O problem + */ + protected void readHorizontalHeader(FontFileReader in) + throws IOException { + seekTab(in, "hhea", 4); + ascender = in.readTTFShort(); // Use sTypoAscender in "OS/2" table? + descender = in.readTTFShort(); // Use sTypoDescender in "OS/2" table? + + in.skip(2 + 2 + 3 * 2 + 8 * 2); + nhmtx = in.readTTFUShort(); + getLogger().debug("Number of horizontal metrics: " + nhmtx); + + //Check OS/2 table for ascender/descender if necessary + if (ascender == 0 || descender == 0) { + seekTab(in, "OS/2", 68); + if (this.currentDirTab.getLength() >= 78) { + ascender = in.readTTFShort(); //sTypoAscender + descender = in.readTTFShort(); //sTypoDescender + } + } + + } + + /** + * Read "hmtx" table and put the horizontal metrics + * in the mtxTab array. If the number of metrics is less + * than the number of glyphs (eg fixed size fonts), extend + * the mtxTab array and fill in the missing widths + * @param in FontFileReader to read the hmtx table from + * @throws IOException in case of an I/O problem + */ + protected void readHorizontalMetrics(FontFileReader in) + throws IOException { + seekTab(in, "hmtx", 0); + + int mtxSize = Math.max(numberOfGlyphs, nhmtx); + mtxTab = new TTFMtxEntry[mtxSize]; + + getLogger().debug("*** Widths array: \n"); + for (int i = 0; i < mtxSize; i++) { + mtxTab[i] = new TTFMtxEntry(); + } + for (int i = 0; i < nhmtx; i++) { + mtxTab[i].setWx(in.readTTFUShort()); + mtxTab[i].setLsb(in.readTTFUShort()); + + if (getLogger().isDebugEnabled()) { + getLogger().debug(" width[" + i + "] = " + + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";"); + } + } + + if (nhmtx < mtxSize) { + // Fill in the missing widths + int lastWidth = mtxTab[nhmtx - 1].getWx(); + for (int i = nhmtx; i < mtxSize; i++) { + mtxTab[i].setWx(lastWidth); + mtxTab[i].setLsb(in.readTTFUShort()); + } + } + } + + + /** + * Read the "post" table + * containing the PostScript names of the glyphs. + */ + private final void readPostScript(FontFileReader in) throws IOException { + seekTab(in, "post", 0); + postFormat = in.readTTFLong(); + italicAngle = in.readTTFULong(); + underlinePosition = in.readTTFShort(); + underlineThickness = in.readTTFShort(); + isFixedPitch = in.readTTFULong(); + + //Skip memory usage values + in.skip(4 * 4); + + getLogger().debug("PostScript format: " + postFormat); + switch (postFormat) { + case 0x00010000: + getLogger().debug("PostScript format 1"); + for (int i = 0; i < Glyphs.MAC_GLYPH_NAMES.length; i++) { + mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[i]); + } + break; + case 0x00020000: + getLogger().debug("PostScript format 2"); + int numGlyphStrings = 0; + + // Read Number of Glyphs + int l = in.readTTFUShort(); + + // Read indexes + for (int i = 0; i < l; i++) { + mtxTab[i].setIndex(in.readTTFUShort()); + + if (mtxTab[i].getIndex() > 257) { + //Index is not in the Macintosh standard set + numGlyphStrings++; + } + + if (getLogger().isDebugEnabled()) { + getLogger().debug("PostScript index: " + mtxTab[i].getIndexAsString()); + } + } + + // firstChar=minIndex; + String[] psGlyphsBuffer = new String[numGlyphStrings]; + if (getLogger().isDebugEnabled()) { + getLogger().debug("Reading " + numGlyphStrings + + " glyphnames, that are not in the standard Macintosh" + + " set. Total number of glyphs=" + l); + } + for (int i = 0; i < psGlyphsBuffer.length; i++) { + psGlyphsBuffer[i] = in.readTTFString(in.readTTFUByte()); + } + + //Set glyph names + for (int i = 0; i < l; i++) { + if (mtxTab[i].getIndex() < NMACGLYPHS) { + mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[mtxTab[i].getIndex()]); + } else { + if (!mtxTab[i].isIndexReserved()) { + int k = mtxTab[i].getIndex() - NMACGLYPHS; + + if (getLogger().isDebugEnabled()) { + getLogger().debug(k + " i=" + i + " mtx=" + mtxTab.length + + " ps=" + psGlyphsBuffer.length); + } + + mtxTab[i].setName(psGlyphsBuffer[k]); + } + } + } + + break; + case 0x00030000: + // PostScript format 3 contains no glyph names + getLogger().debug("PostScript format 3"); + break; + default: + getLogger().error("Unknown PostScript format: " + postFormat); + } + } + + + /** + * Read the "OS/2" table + */ + private final void readOS2(FontFileReader in) throws IOException { + // Check if font is embeddable + if (dirTabs.get("OS/2") != null) { + seekTab(in, "OS/2", 2 * 4); + int fsType = in.readTTFUShort(); + if (fsType == 2) { + isEmbeddable = false; + } else { + isEmbeddable = true; + } + } else { + isEmbeddable = true; + } + } + + /** + * Read the "loca" table. + * @param in FontFileReader to read from + * @throws IOException In case of a I/O problem + */ + protected final void readIndexToLocation(FontFileReader in) + throws IOException { + seekTab(in, "loca", 0); + for (int i = 0; i < numberOfGlyphs; i++) { + mtxTab[i].setOffset(locaFormat == 1 ? in.readTTFULong() + : (in.readTTFUShort() << 1)); + } + lastLoca = (locaFormat == 1 ? in.readTTFULong() + : (in.readTTFUShort() << 1)); + } + + /** + * Read the "glyf" table to find the bounding boxes. + * @param in FontFileReader to read from + * @throws IOException In case of a I/O problem + */ + private final void readGlyf(FontFileReader in) throws IOException { + TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("glyf"); + for (int i = 0; i < (numberOfGlyphs - 1); i++) { + if (mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) { + in.seekSet(dirTab.getOffset() + mtxTab[i].getOffset()); + in.skip(2); + final int[] bbox = { + in.readTTFShort(), + in.readTTFShort(), + in.readTTFShort(), + in.readTTFShort()}; + mtxTab[i].setBoundingBox(bbox); + } else { + mtxTab[i].setBoundingBox(mtxTab[0].getBoundingBox()); + } + } + + + long n = ((TTFDirTabEntry)dirTabs.get("glyf")).getOffset(); + for (int i = 0; i < numberOfGlyphs; i++) { + if ((i + 1) >= mtxTab.length + || mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) { + in.seekSet(n + mtxTab[i].getOffset()); + in.skip(2); + final int[] bbox = { + in.readTTFShort(), + in.readTTFShort(), + in.readTTFShort(), + in.readTTFShort()}; + mtxTab[i].setBoundingBox(bbox); + } else { + /**@todo Verify that this is correct, looks like a copy/paste bug (jm)*/ + final int bbox0 = mtxTab[0].getBoundingBox()[0]; + final int[] bbox = {bbox0, bbox0, bbox0, bbox0}; + mtxTab[i].setBoundingBox(bbox); + /* Original code + mtxTab[i].bbox[0] = mtxTab[0].bbox[0]; + mtxTab[i].bbox[1] = mtxTab[0].bbox[0]; + mtxTab[i].bbox[2] = mtxTab[0].bbox[0]; + mtxTab[i].bbox[3] = mtxTab[0].bbox[0]; */ + } + getLogger().debug(mtxTab[i].toString(this)); + } + } + + /** + * Read the "name" table. + * @param in FontFileReader to read from + * @throws IOException In case of a I/O problem + */ + private final void readName(FontFileReader in) throws IOException { + seekTab(in, "name", 2); + int i = in.getCurrentPos(); + int n = in.readTTFUShort(); + int j = in.readTTFUShort() + i - 2; + i += 2 * 2; + + while (n-- > 0) { + // getLogger().debug("Iteration: " + n); + in.seekSet(i); + final int platformID = in.readTTFUShort(); + final int encodingID = in.readTTFUShort(); + /*final int language_id =*/ in.readTTFUShort(); //Skip language id + + int k = in.readTTFUShort(); + int l = in.readTTFUShort(); + + if (((platformID == 1 || platformID == 3) && (encodingID == 0 || encodingID == 1)) + && (k == 1 || k == 2 || k == 0 || k == 4 || k == 6)) { + // if (k==1 || k==2 || k==0 || k==4 || k==6) { + in.seekSet(j + in.readTTFUShort()); + String txt = in.readTTFString(l); + // getLogger().debug(platform_id + " " + encoding_id + // + " " + k + " " + txt); + switch (k) { + case 0: + notice = txt; + break; + case 1: + familyName = txt; + break; + case 2: + subFamilyName = txt; + break; + case 4: + fullName = txt; + break; + case 6: + fontName = txt; + break; + } + if (!notice.equals("") + && !fullName.equals("") + && !fontName.equals("") + && !familyName.equals("") + && !subFamilyName.equals("")) { + break; + } + } + i += 6 * 2; + } + } + + /** + * Read the "PCLT" table to find xHeight and capHeight. + * @param in FontFileReader to read from + * @throws IOException In case of a I/O problem + */ + private final void readPCLT(FontFileReader in) throws IOException { + TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("PCLT"); + if (dirTab != null) { + in.seekSet(dirTab.getOffset() + 4 + 4 + 2); + xHeight = in.readTTFUShort(); + in.skip(2 * 2); + capHeight = in.readTTFUShort(); + in.skip(2 + 16 + 8 + 6 + 1 + 1); + + int serifStyle = in.readTTFUByte(); + serifStyle = serifStyle >> 6; + serifStyle = serifStyle & 3; + if (serifStyle == 1) { + hasSerifs = false; + } else { + hasSerifs = true; + } + } else { + // Approximate capHeight from height of "H" + // It's most unlikly that a font misses the PCLT table + // This also assumes that psocriptnames exists ("H") + // Should look it up int the cmap (that wouldn't help + // for charsets without H anyway...) + for (int i = 0; i < mtxTab.length; i++) { + if ("H".equals(mtxTab[i].getName())) { + capHeight = mtxTab[i].getBoundingBox()[3] - mtxTab[i].getBoundingBox()[1]; + } + } + } + } + + /** + * Read the kerning table, create a table for both CIDs and + * winAnsiEncoding. + * @param in FontFileReader to read from + * @throws IOException In case of a I/O problem + */ + private final void readKerning(FontFileReader in) throws IOException { + // Read kerning + kerningTab = new java.util.HashMap(); + ansiKerningTab = new java.util.HashMap(); + TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("kern"); + if (dirTab != null) { + seekTab(in, "kern", 2); + for (int n = in.readTTFUShort(); n > 0; n--) { + in.skip(2 * 2); + int k = in.readTTFUShort(); + if (!((k & 1) != 0) || (k & 2) != 0 || (k & 4) != 0) { + return; + } + if ((k >> 8) != 0) { + continue; + } + + k = in.readTTFUShort(); + in.skip(3 * 2); + while (k-- > 0) { + int i = in.readTTFUShort(); + int j = in.readTTFUShort(); + int kpx = in.readTTFShort(); + if (kpx != 0) { + // CID table + Integer iObj = new Integer(i); + Map adjTab = (Map)kerningTab.get(iObj); + if (adjTab == null) { + adjTab = new java.util.HashMap(); + } + adjTab.put(new Integer(j), + new Integer((int)convertTTFUnit2PDFUnit(kpx))); + kerningTab.put(iObj, adjTab); + } + } + } + // getLogger().debug(kerningTab.toString()); + + // Create winAnsiEncoded kerning table + Iterator ae = kerningTab.keySet().iterator(); + while (ae.hasNext()) { + Integer cidKey = (Integer)ae.next(); + Map akpx = new java.util.HashMap(); + Map ckpx = (Map)kerningTab.get(cidKey); + + Iterator aee = ckpx.keySet().iterator(); + while (aee.hasNext()) { + Integer cidKey2 = (Integer)aee.next(); + Integer kern = (Integer)ckpx.get(cidKey2); + + Iterator uniMap = mtxTab[cidKey2.intValue()].getUnicodeIndex().listIterator(); + while (uniMap.hasNext()) { + Integer unicodeKey = (Integer)uniMap.next(); + Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue()); + for (int u = 0; u < ansiKeys.length; u++) { + akpx.put(ansiKeys[u], kern); + } + } + } + + if (akpx.size() > 0) { + Iterator uniMap = mtxTab[cidKey.intValue()].getUnicodeIndex().listIterator(); + while (uniMap.hasNext()) { + Integer unicodeKey = (Integer)uniMap.next(); + Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue()); + for (int u = 0; u < ansiKeys.length; u++) { + ansiKerningTab.put(ansiKeys[u], akpx); + } + } + } + } + } + } + + /** + * Return a List with TTFCmapEntry. + * @return A list of TTFCmapEntry objects + */ + public List getCMaps() { + return cmaps; + } + + /** + * Check if this is a TrueType collection and that the given + * name exists in the collection. + * If it does, set offset in fontfile to the beginning of + * the Table Directory for that font. + * @param in FontFileReader to read from + * @param name The name to check + * @return True if not collection or font name present, false otherwise + * @throws IOException In case of an I/O problem + */ + protected final boolean checkTTC(FontFileReader in, String name) throws IOException { + String tag = in.readTTFString(4); + + if ("ttcf".equals(tag)) { + // This is a TrueType Collection + in.skip(4); + + // Read directory offsets + int numDirectories = (int)in.readTTFULong(); + // int numDirectories=in.readTTFUShort(); + long[] dirOffsets = new long[numDirectories]; + for (int i = 0; i < numDirectories; i++) { + dirOffsets[i] = in.readTTFULong(); + } + + getLogger().debug("This is a TrueType collection file with" + + numDirectories + " fonts"); + getLogger().debug("Containing the following fonts: "); + // Read all the directories and name tables to check + // If the font exists - this is a bit ugly, but... + boolean found = false; + + // Iterate through all name tables even if font + // Is found, just to show all the names + long dirTabOffset = 0; + for (int i = 0; (i < numDirectories); i++) { + in.seekSet(dirOffsets[i]); + readDirTabs(in); + + readName(in); + + if (fullName.equals(name)) { + found = true; + dirTabOffset = dirOffsets[i]; + getLogger().debug("* " + fullName); + } else { + getLogger().debug(fullName); + } + + // Reset names + notice = ""; + fullName = ""; + familyName = ""; + fontName = ""; + subFamilyName = ""; + } + + in.seekSet(dirTabOffset); + return found; + } else { + in.seekSet(0); + return true; + } + } + + /* + * Helper classes, they are not very efficient, but that really + * doesn't matter... + */ + private Integer[] unicodeToWinAnsi(int unicode) { + List ret = new java.util.ArrayList(); + for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) { + if (unicode == Glyphs.WINANSI_ENCODING[i]) { + ret.add(new Integer(i)); + } + } + return (Integer[])ret.toArray(new Integer[0]); + } + + /** + * Dumps a few informational values to System.out. + */ + public void printStuff() { + System.out.println("Font name: " + fontName); + System.out.println("Full name: " + fullName); + System.out.println("Family name: " + familyName); + System.out.println("Subfamily name: " + subFamilyName); + System.out.println("Notice: " + notice); + System.out.println("xHeight: " + (int)convertTTFUnit2PDFUnit(xHeight)); + System.out.println("capheight: " + (int)convertTTFUnit2PDFUnit(capHeight)); + + int italic = (int)(italicAngle >> 16); + System.out.println("Italic: " + italic); + System.out.print("ItalicAngle: " + (short)(italicAngle / 0x10000)); + if ((italicAngle % 0x10000) > 0) { + System.out.print("." + + (short)((italicAngle % 0x10000) * 1000) + / 0x10000); + } + System.out.println(); + System.out.println("Ascender: " + convertTTFUnit2PDFUnit(ascender)); + System.out.println("Descender: " + convertTTFUnit2PDFUnit(descender)); + System.out.println("FontBBox: [" + (int)convertTTFUnit2PDFUnit(fontBBox1) + + " " + (int)convertTTFUnit2PDFUnit(fontBBox2) + " " + + (int)convertTTFUnit2PDFUnit(fontBBox3) + " " + + (int)convertTTFUnit2PDFUnit(fontBBox4) + "]"); + } + + /** + * Static main method to get info about a TrueType font. + * @param args The command line arguments + */ + public static void main(String[] args) { + int level = ConsoleLogger.LEVEL_WARN; + Logger log = new ConsoleLogger(level); + try { + TTFFile ttfFile = new TTFFile(); + ttfFile.enableLogging(log); + + FontFileReader reader = new FontFileReader(args[0]); + + String name = null; + if (args.length >= 2) { + name = args[1]; + } + + ttfFile.readFont(reader, name); + ttfFile.printStuff(); + + } catch (IOException ioe) { + log.error("Problem reading font: " + ioe.toString(), ioe); + } + } + +} + + +/** + * Key-value helper class + */ +class UnicodeMapping { + + private int uIdx; + private int gIdx; + + UnicodeMapping(int gIdx, int uIdx) { + this.uIdx = uIdx; + this.gIdx = gIdx; + } + + /** + * Returns the gIdx. + * @return int + */ + public int getGIdx() { + return gIdx; + } + + /** + * Returns the uIdx. + * @return int + */ + public int getUIdx() { + return uIdx; + } + +} diff --git a/src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java new file mode 100644 index 000000000..fde6bd8f8 --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/TTFMtxEntry.java @@ -0,0 +1,226 @@ +/* + * $Id: TTFMtxEntry.java,v 1.3 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +import java.util.List; + +/** + * This class represents a TrueType Mtx Entry. + */ +class TTFMtxEntry { + + private int wx; + private int lsb; + private String name = ""; + private int index; + private List unicodeIndex = new java.util.ArrayList(); + private int[] boundingBox = new int[4]; + private long offset; + private byte found = 0; + + /** + * Returns a String representation of this object. + * + * @param t TTFFile to use for unit conversion + * @return String String representation + */ + public String toString(TTFFile t) { + return "Glyph " + name + " index: " + getIndexAsString() + " bbox [" + + t.convertTTFUnit2PDFUnit(boundingBox[0]) + " " + + t.convertTTFUnit2PDFUnit(boundingBox[1]) + " " + + t.convertTTFUnit2PDFUnit(boundingBox[2]) + " " + + t.convertTTFUnit2PDFUnit(boundingBox[3]) + "] wx: " + + t.convertTTFUnit2PDFUnit(wx); + } + + /** + * Returns the boundingBox. + * @return int[] + */ + public int[] getBoundingBox() { + return boundingBox; + } + + /** + * Sets the boundingBox. + * @param boundingBox The boundingBox to set + */ + public void setBoundingBox(int[] boundingBox) { + this.boundingBox = boundingBox; + } + + /** + * Returns the found. + * @return byte + */ + public byte getFound() { + return found; + } + + /** + * Returns the index. + * @return int + */ + public int getIndex() { + return index; + } + + /** + * Determines whether this index represents a reserved character. + * @return True if it is reserved + */ + public boolean isIndexReserved() { + return (getIndex() >= 32768) && (getIndex() <= 65535); + } + + /** + * Returns a String representation of the index taking into account if + * the index is in the reserved range. + * @return index as String + */ + public String getIndexAsString() { + if (isIndexReserved()) { + return Integer.toString(getIndex()) + " (reserved)"; + } else { + return Integer.toString(getIndex()); + } + } + + /** + * Returns the lsb. + * @return int + */ + public int getLsb() { + return lsb; + } + + /** + * Returns the name. + * @return String + */ + public String getName() { + return name; + } + + /** + * Returns the offset. + * @return long + */ + public long getOffset() { + return offset; + } + + /** + * Returns the unicodeIndex. + * @return List + */ + public List getUnicodeIndex() { + return unicodeIndex; + } + + /** + * Returns the wx. + * @return int + */ + public int getWx() { + return wx; + } + + /** + * Sets the found. + * @param found The found to set + */ + public void setFound(byte found) { + this.found = found; + } + + /** + * Sets the index. + * @param index The index to set + */ + public void setIndex(int index) { + this.index = index; + } + + /** + * Sets the lsb. + * @param lsb The lsb to set + */ + public void setLsb(int lsb) { + this.lsb = lsb; + } + + /** + * Sets the name. + * @param name The name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * Sets the offset. + * @param offset The offset to set + */ + public void setOffset(long offset) { + this.offset = offset; + } + + /** + * Sets the wx. + * @param wx The wx to set + */ + public void setWx(int wx) { + this.wx = wx; + } + + +} diff --git a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java new file mode 100644 index 000000000..cd230a4e5 --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java @@ -0,0 +1,886 @@ +/* + * $Id: TTFSubSetFile.java,v 1.4 2003/03/06 17:43:06 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.truetype; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.List; + + +/** + * Reads a TrueType file and generates a subset + * that can be used to embed a TrueType CID font. + * TrueType tables needed for embedded CID fonts are: + * "head", "hhea", "loca", "maxp", "cvt ", "prep", "glyf", "hmtx" and "fpgm". + * The TrueType spec can be found at the Microsoft + * Typography site: http://www.microsoft.com/truetype/ + */ +public class TTFSubSetFile extends TTFFile { + + private byte[] output = null; + private int realSize = 0; + private int currentPos = 0; + + /* + * Offsets in name table to be filled out by table. + * The offsets are to the checkSum field + */ + private int cvtDirOffset = 0; + private int fpgmDirOffset = 0; + private int glyfDirOffset = 0; + private int headDirOffset = 0; + private int hheaDirOffset = 0; + private int hmtxDirOffset = 0; + private int locaDirOffset = 0; + private int maxpDirOffset = 0; + private int prepDirOffset = 0; + + private int checkSumAdjustmentOffset = 0; + private int locaOffset = 0; + + /** + * Initalize the output array + */ + private void init(int size) { + output = new byte[size]; + realSize = 0; + currentPos = 0; + + // createDirectory() + } + + /** + * Create the directory table + */ + private void createDirectory() { + int numTables = 9; + // Create the TrueType header + writeByte((byte)0); + writeByte((byte)1); + writeByte((byte)0); + writeByte((byte)0); + realSize += 4; + + writeUShort(numTables); + realSize += 2; + + // Create searchRange, entrySelector and rangeShift + int maxPow = maxPow2(numTables); + int searchRange = maxPow * 16; + writeUShort(searchRange); + realSize += 2; + + writeUShort(maxPow); + realSize += 2; + + writeUShort((numTables * 16) - searchRange); + realSize += 2; + + // Create space for the table entries + writeString("cvt "); + cvtDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + if (hasFpgm()) { + writeString("fpgm"); + fpgmDirOffset = currentPos; + currentPos += 12; + realSize += 16; + } + + writeString("glyf"); + glyfDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("head"); + headDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("hhea"); + hheaDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("hmtx"); + hmtxDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("loca"); + locaDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("maxp"); + maxpDirOffset = currentPos; + currentPos += 12; + realSize += 16; + + writeString("prep"); + prepDirOffset = currentPos; + currentPos += 12; + realSize += 16; + } + + + /** + * Copy the cvt table as is from original font to subset font + */ + private void createCvt(FontFileReader in) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("cvt "); + if (entry != null) { + pad4(); + seekTab(in, "cvt ", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(cvtDirOffset, checksum); + writeULong(cvtDirOffset + 4, currentPos); + writeULong(cvtDirOffset + 8, (int)entry.getLength()); + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + throw new IOException("Can't find cvt table"); + } + } + + + private boolean hasFpgm() { + return (dirTabs.get("fpgm") != null); + } + + + /** + * Copy the fpgm table as is from original font to subset font + */ + private void createFpgm(FontFileReader in) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("fpgm"); + if (entry != null) { + pad4(); + seekTab(in, "fpgm", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(fpgmDirOffset, checksum); + writeULong(fpgmDirOffset + 4, currentPos); + writeULong(fpgmDirOffset + 8, (int)entry.getLength()); + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + //fpgm table is optional + //throw new IOException("Can't find fpgm table"); + } + } + + + + /** + * Create an empty loca table without updating checksum + */ + private void createLoca(int size) throws IOException { + pad4(); + locaOffset = currentPos; + writeULong(locaDirOffset + 4, currentPos); + writeULong(locaDirOffset + 8, size * 4 + 4); + currentPos += size * 4 + 4; + realSize += size * 4 + 4; + } + + + /** + * Copy the maxp table as is from original font to subset font + * and set num glyphs to size + */ + private void createMaxp(FontFileReader in, int size) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("maxp"); + if (entry != null) { + pad4(); + seekTab(in, "maxp", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + writeUShort(currentPos + 4, size); + + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(maxpDirOffset, checksum); + writeULong(maxpDirOffset + 4, currentPos); + writeULong(maxpDirOffset + 8, (int)entry.getLength()); + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + throw new IOException("Can't find maxp table"); + } + } + + + /** + * Copy the prep table as is from original font to subset font + */ + private void createPrep(FontFileReader in) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("prep"); + if (entry != null) { + pad4(); + seekTab(in, "prep", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(prepDirOffset, checksum); + writeULong(prepDirOffset + 4, currentPos); + writeULong(prepDirOffset + 8, (int)entry.getLength()); + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + throw new IOException("Can't find prep table"); + } + } + + + /** + * Copy the hhea table as is from original font to subset font + * and fill in size of hmtx table + */ + private void createHhea(FontFileReader in, int size) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hhea"); + if (entry != null) { + pad4(); + seekTab(in, "hhea", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + writeUShort((int)entry.getLength() + currentPos - 2, size); + + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(hheaDirOffset, checksum); + writeULong(hheaDirOffset + 4, currentPos); + writeULong(hheaDirOffset + 8, (int)entry.getLength()); + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + throw new IOException("Can't find hhea table"); + } + } + + + /** + * Copy the head table as is from original font to subset font + * and set indexToLocaFormat to long and set + * checkSumAdjustment to 0, store offset to checkSumAdjustment + * in checkSumAdjustmentOffset + */ + private void createHead(FontFileReader in) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("head"); + if (entry != null) { + pad4(); + seekTab(in, "head", 0); + System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()), + 0, output, currentPos, (int)entry.getLength()); + + checkSumAdjustmentOffset = currentPos + 8; + output[currentPos + 8] = 0; // Set checkSumAdjustment to 0 + output[currentPos + 9] = 0; + output[currentPos + 10] = 0; + output[currentPos + 11] = 0; + output[currentPos + 50] = 0; // long locaformat + output[currentPos + 51] = 1; // long locaformat + + int checksum = getCheckSum(currentPos, (int)entry.getLength()); + writeULong(headDirOffset, checksum); + writeULong(headDirOffset + 4, currentPos); + writeULong(headDirOffset + 8, (int)entry.getLength()); + + currentPos += (int)entry.getLength(); + realSize += (int)entry.getLength(); + } else { + throw new IOException("Can't find head table"); + } + } + + + /** + * Create the glyf table and fill in loca table + */ + private void createGlyf(FontFileReader in, + Map glyphs) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf"); + int size = 0; + int start = 0; + int endOffset = 0; // Store this as the last loca + if (entry != null) { + pad4(); + start = currentPos; + + /* Loca table must be in order by glyph index, so build + * an array first and then write the glyph info and + * location offset. + */ + int[] origIndexes = new int[glyphs.size()]; + + Iterator e = glyphs.keySet().iterator(); + while (e.hasNext()) { + Integer origIndex = (Integer)e.next(); + Integer subsetIndex = (Integer)glyphs.get(origIndex); + origIndexes[subsetIndex.intValue()] = origIndex.intValue(); + } + + for (int i = 0; i < origIndexes.length; i++) { + int glyphLength = 0; + int nextOffset = 0; + int origGlyphIndex = origIndexes[i]; + if (origGlyphIndex >= (mtxTab.length - 1)) { + nextOffset = (int)lastLoca; + } else { + nextOffset = (int)mtxTab[origGlyphIndex + 1].getOffset(); + } + glyphLength = nextOffset - (int)mtxTab[origGlyphIndex].getOffset(); + + // Copy glyph + System.arraycopy( + in.getBytes((int)entry.getOffset() + (int)mtxTab[origGlyphIndex].getOffset(), + glyphLength), 0, + output, currentPos, + glyphLength); + + + // Update loca table + writeULong(locaOffset + i * 4, currentPos - start); + if ((currentPos - start + glyphLength) > endOffset) { + endOffset = (currentPos - start + glyphLength); + } + + currentPos += glyphLength; + realSize += glyphLength; + + } + + size = currentPos - start; + + int checksum = getCheckSum(start, size); + writeULong(glyfDirOffset, checksum); + writeULong(glyfDirOffset + 4, start); + writeULong(glyfDirOffset + 8, size); + currentPos += 12; + realSize += 12; + + // Update loca checksum and last loca index + writeULong(locaOffset + glyphs.size() * 4, endOffset); + + checksum = getCheckSum(locaOffset, glyphs.size() * 4 + 4); + writeULong(locaDirOffset, checksum); + } else { + throw new IOException("Can't find glyf table"); + } + } + + + /** + * Create the hmtx table by copying metrics from original + * font to subset font. The glyphs Map contains an + * Integer key and Integer value that maps the original + * metric (key) to the subset metric (value) + */ + private void createHmtx(FontFileReader in, + Map glyphs) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hmtx"); + + int longHorMetricSize = glyphs.size() * 2; + int leftSideBearingSize = glyphs.size() * 2; + int hmtxSize = longHorMetricSize + leftSideBearingSize; + + if (entry != null) { + pad4(); + //int offset = (int)entry.offset; + Iterator e = glyphs.keySet().iterator(); + while (e.hasNext()) { + Integer origIndex = (Integer)e.next(); + Integer subsetIndex = (Integer)glyphs.get(origIndex); + + writeUShort(currentPos + subsetIndex.intValue() * 4, + mtxTab[origIndex.intValue()].getWx()); + writeUShort(currentPos + subsetIndex.intValue() * 4 + 2, + mtxTab[origIndex.intValue()].getLsb()); + } + + int checksum = getCheckSum(currentPos, hmtxSize); + writeULong(hmtxDirOffset, checksum); + writeULong(hmtxDirOffset + 4, currentPos); + writeULong(hmtxDirOffset + 8, hmtxSize); + currentPos += hmtxSize; + realSize += hmtxSize; + } else { + throw new IOException("Can't find hmtx table"); + } + } + + /** + * Returns a List containing the glyph itself plus all glyphs + * that this composite glyph uses + */ + private List getIncludedGlyphs(FontFileReader in, int glyphOffset, + Integer glyphIdx) throws IOException { + List ret = new java.util.ArrayList(); + ret.add(glyphIdx); + int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() + 10; + Integer compositeIdx = null; + int flags = 0; + boolean moreComposites = true; + while (moreComposites) { + flags = in.readTTFUShort(offset); + compositeIdx = new Integer(in.readTTFUShort(offset + 2)); + ret.add(compositeIdx); + + offset += 4; + if ((flags & 1) > 0) { + // ARG_1_AND_ARG_2_ARE_WORDS + offset += 4; + } else { + offset += 2; + } + + if ((flags & 8) > 0) { + offset += 2; // WE_HAVE_A_SCALE + } else if ((flags & 64) > 0) { + offset += 4; // WE_HAVE_AN_X_AND_Y_SCALE + } else if ((flags & 128) > 0) { + offset += 8; // WE_HAVE_A_TWO_BY_TWO + } + + if ((flags & 32) > 0) { + moreComposites = true; + } else { + moreComposites = false; + } + } + + return ret; + } + + + /** + * Rewrite all compositepointers in glyphindex glyphIdx + * + */ + private void remapComposite(FontFileReader in, Map glyphs, + int glyphOffset, + Integer glyphIdx) throws IOException { + int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() + + 10; + + Integer compositeIdx = null; + int flags = 0; + boolean moreComposites = true; + + while (moreComposites) { + flags = in.readTTFUShort(offset); + compositeIdx = new Integer(in.readTTFUShort(offset + 2)); + Integer newIdx = (Integer)glyphs.get(compositeIdx); + if (newIdx == null) { + // This errormessage would look much better + // if the fontname was printed to + //log.error("An embedded font " + // + "contains bad glyph data. " + // + "Characters might not display " + // + "correctly."); + moreComposites = false; + continue; + } + + in.writeTTFUShort(offset + 2, newIdx.intValue()); + + offset += 4; + + if ((flags & 1) > 0) { + // ARG_1_AND_ARG_2_ARE_WORDS + offset += 4; + } else { + offset += 2; + } + + if ((flags & 8) > 0) { + offset += 2; // WE_HAVE_A_SCALE + } else if ((flags & 64) > 0) { + offset += 4; // WE_HAVE_AN_X_AND_Y_SCALE + } else if ((flags & 128) > 0) { + offset += 8; // WE_HAVE_A_TWO_BY_TWO + } + + if ((flags & 32) > 0) { + moreComposites = true; + } else { + moreComposites = false; + } + } + } + + + /** + * Scan all the original glyphs for composite glyphs and add those glyphs + * to the glyphmapping also rewrite the composite glyph pointers to the new + * mapping + */ + private void scanGlyphs(FontFileReader in, + Map glyphs) throws IOException { + TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf"); + Map newComposites = null; + Map allComposites = new java.util.HashMap(); + + int newIndex = glyphs.size(); + + if (entry != null) { + while (newComposites == null || newComposites.size() > 0) { + // Inefficient to iterate through all glyphs + newComposites = new java.util.HashMap(); + + Iterator e = glyphs.keySet().iterator(); + while (e.hasNext()) { + Integer origIndex = (Integer)e.next(); + + if (in.readTTFShort(entry.getOffset() + + mtxTab[origIndex.intValue()].getOffset()) < 0) { + // origIndex is a composite glyph + allComposites.put(origIndex, glyphs.get(origIndex)); + List composites = + getIncludedGlyphs(in, (int)entry.getOffset(), + origIndex); + + // Iterate through all composites pointed to + // by this composite and check if they exists + // in the glyphs map, add them if not. + Iterator cps = composites.iterator(); + while (cps.hasNext()) { + Integer cIdx = (Integer)cps.next(); + if (glyphs.get(cIdx) == null + && newComposites.get(cIdx) == null) { + newComposites.put(cIdx, + new Integer(newIndex)); + newIndex++; + } + } + } + } + + // Add composites to glyphs + Iterator m = newComposites.keySet().iterator(); + while (m.hasNext()) { + Integer im = (Integer)m.next(); + glyphs.put(im, newComposites.get(im)); + } + } + + // Iterate through all composites to remap their composite index + Iterator ce = allComposites.keySet().iterator(); + while (ce.hasNext()) { + remapComposite(in, glyphs, (int)entry.getOffset(), + (Integer)ce.next()); + } + + } else { + throw new IOException("Can't find glyf table"); + } + } + + + + /** + * Returns a subset of the original font. + * + * @param in FontFileReader to read from + * @param name Name to be checked for in the font file + * @param glyphs Map of glyphs (glyphs has old index as (Integer) key and + * new index as (Integer) value) + * @return A subset of the original font + * @throws IOException in case of an I/O problem + */ + public byte[] readFont(FontFileReader in, String name, + Map glyphs) throws IOException { + + //Check if TrueType collection, and that the name exists in the collection + if (!checkTTC(in, name)) { + throw new IOException("Failed to read font"); + } + + output = new byte[in.getFileSize()]; + + readDirTabs(in); + readFontHeader(in); + getNumGlyphs(in); + readHorizontalHeader(in); + readHorizontalMetrics(in); + readIndexToLocation(in); + + scanGlyphs(in, glyphs); + + createDirectory(); // Create the TrueType header and directory + + createHead(in); + createHhea(in, glyphs.size()); // Create the hhea table + createHmtx(in, glyphs); // Create hmtx table + createMaxp(in, glyphs.size()); // copy the maxp table + + try { + createCvt(in); // copy the cvt table + } catch (IOException ex) { + // Cvt is optional (only required for OpenType (MS) fonts) + //log.error("TrueType warning: " + ex.getMessage()); + } + + try { + createFpgm(in); // copy fpgm table + } catch (IOException ex) { + // Fpgm is optional (only required for OpenType (MS) fonts) + //log.error("TrueType warning: " + ex.getMessage()); + } + + try { + createPrep(in); // copy prep table + } catch (IOException ex) { + // Prep is optional (only required for OpenType (MS) fonts) + //log.error("TrueType warning: " + ex.getMessage()); + } + + try { + createLoca(glyphs.size()); // create empty loca table + } catch (IOException ex) { + // Loca is optional (only required for OpenType (MS) fonts) + //log.error("TrueType warning: " + ex.getMessage()); + } + + try { + createGlyf(in, glyphs); + } catch (IOException ex) { + // Glyf is optional (only required for OpenType (MS) fonts) + //log.error("TrueType warning: " + ex.getMessage()); + } + + pad4(); + createCheckSumAdjustment(); + + byte[] ret = new byte[realSize]; + System.arraycopy(output, 0, ret, 0, realSize); + + return ret; + } + + /** + * writes a ISO-8859-1 string at the currentPosition + * updates currentPosition but not realSize + * @return number of bytes written + */ + private int writeString(String str) { + int length = 0; + try { + byte[] buf = str.getBytes("ISO-8859-1"); + System.arraycopy(buf, 0, output, currentPos, buf.length); + length = buf.length; + currentPos += length; + } catch (java.io.UnsupportedEncodingException e) { + // This should never happen! + } + + return length; + } + + /** + * Appends a byte to the output array, + * updates currentPost but not realSize + */ + private void writeByte(byte b) { + output[currentPos++] = b; + } + + /** + * Appends a USHORT to the output array, + * updates currentPost but not realSize + */ + private void writeUShort(int s) { + byte b1 = (byte)((s >> 8) & 0xff); + byte b2 = (byte)(s & 0xff); + writeByte(b1); + writeByte(b2); + } + + /** + * Appends a USHORT to the output array, + * at the given position without changing currentPos + */ + private void writeUShort(int pos, int s) { + byte b1 = (byte)((s >> 8) & 0xff); + byte b2 = (byte)(s & 0xff); + output[pos] = b1; + output[pos + 1] = b2; + } + + /** + * Appends a ULONG to the output array, + * updates currentPos but not realSize + */ + private void writeULong(int s) { + byte b1 = (byte)((s >> 24) & 0xff); + byte b2 = (byte)((s >> 16) & 0xff); + byte b3 = (byte)((s >> 8) & 0xff); + byte b4 = (byte)(s & 0xff); + writeByte(b1); + writeByte(b2); + writeByte(b3); + writeByte(b4); + } + + /** + * Appends a ULONG to the output array, + * at the given position without changing currentPos + */ + private void writeULong(int pos, int s) { + byte b1 = (byte)((s >> 24) & 0xff); + byte b2 = (byte)((s >> 16) & 0xff); + byte b3 = (byte)((s >> 8) & 0xff); + byte b4 = (byte)(s & 0xff); + output[pos] = b1; + output[pos + 1] = b2; + output[pos + 2] = b3; + output[pos + 3] = b4; + } + + /** + * Read a signed short value at given position + */ + private short readShort(int pos) { + int ret = readUShort(pos); + return (short)ret; + } + + /** + * Read a unsigned short value at given position + */ + private int readUShort(int pos) { + int ret = (int)output[pos]; + if (ret < 0) { + ret += 256; + } + ret = ret << 8; + if ((int)output[pos + 1] < 0) { + ret |= (int)output[pos + 1] + 256; + } else { + ret |= (int)output[pos + 1]; + } + + return ret; + } + + /** + * Create a padding in the fontfile to align + * on a 4-byte boundary + */ + private void pad4() { + int padSize = currentPos % 4; + for (int i = 0; i < padSize; i++) { + output[currentPos++] = 0; + realSize++; + } + } + + /** + * Returns the maximum power of 2 <= max + */ + private int maxPow2(int max) { + int i = 0; + while (Math.pow(2, (double)i) < max) { + i++; + } + + return (i - 1); + } + + private int log2(int num) { + return (int)(Math.log((double)num) / Math.log(2)); + } + + + private int getCheckSum(int start, int size) { + return (int)getLongCheckSum(start, size); + } + + private long getLongCheckSum(int start, int size) { + // All the tables here are aligned on four byte boundaries + // Add remainder to size if it's not a multiple of 4 + int remainder = size % 4; + if (remainder != 0) { + size += remainder; + } + + long sum = 0; + + for (int i = 0; i < size; i += 4) { + int l = (int)(output[start + i] << 24); + l += (int)(output[start + i + 1] << 16); + l += (int)(output[start + i + 2] << 16); + l += (int)(output[start + i + 3] << 16); + sum += l; + if (sum > 0xffffffff) { + sum = sum - 0xffffffff; + } + } + + return sum; + } + + private void createCheckSumAdjustment() { + long sum = getLongCheckSum(0, realSize); + int checksum = (int)(0xb1b0afba - sum); + writeULong(checkSumAdjustmentOffset, checksum); + } + +} + + + diff --git a/src/java/org/apache/fop/fonts/truetype/package.html b/src/java/org/apache/fop/fonts/truetype/package.html new file mode 100644 index 000000000..6517f9889 --- /dev/null +++ b/src/java/org/apache/fop/fonts/truetype/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.fonts.truetype Package + +

Classes for TrueType fonts.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/type1/PFBData.java b/src/java/org/apache/fop/fonts/type1/PFBData.java new file mode 100644 index 000000000..95060cb12 --- /dev/null +++ b/src/java/org/apache/fop/fonts/type1/PFBData.java @@ -0,0 +1,192 @@ +/* + * $Id: PFBData.java,v 1.3 2003/03/06 17:43:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.type1; + +import java.io.OutputStream; +import java.io.IOException; + +/** + * Class that represents the contents of a PFB file. + * + * @see PFBParser + */ +public class PFBData { + + /** + * Raw format, no special file structure + */ + public static final int PFB_RAW = 0; + + /** + * PC format + */ + public static final int PFB_PC = 1; + + /** + * MAC Format (unsupported, yet) + */ + public static final int PFB_MAC = 2; + + private int pfbFormat; //One of the PFB_* constants + private byte[] headerSegment; + private byte[] encryptedSegment; + private byte[] trailerSegment; + + + /** + * Sets the PFB format the font was loaded with. + * @param format one of the PFB_* constants + */ + public void setPFBFormat(int format) { + switch (format) { + case PFB_RAW: + case PFB_PC: + this.pfbFormat = format; + break; + case PFB_MAC: + throw new UnsupportedOperationException("Mac format is not yet implemented"); + default: + throw new IllegalArgumentException("Invalid value for PFB format: " + format); + } + } + + + /** + * Returns the format the font was loaded with. + * @return int one of the PFB_* constants + */ + public int getPFBFormat() { + return this.pfbFormat; + } + + /** + * Sets the header segment of the font file. + * @param headerSeg the header segment + */ + public void setHeaderSegment(byte[] headerSeg) { + this.headerSegment = headerSeg; + } + + /** + * Sets the encrypted segment of the font file. + * @param encryptedSeg the encrypted segment + */ + public void setEncryptedSegment(byte[] encryptedSeg) { + this.encryptedSegment = encryptedSeg; + } + + /** + * Sets the trailer segment of the font file. + * @param trailerSeg the trailer segment + */ + public void setTrailerSegment(byte[] trailerSeg) { + this.trailerSegment = trailerSeg; + } + + /** + * Returns the full length of the raw font file. + * @return int the raw file length + */ + public int getLength() { + return getLength1() + getLength2() + getLength3(); + } + + + /** + * Returns the Length1 (length of the header segment). + * @return int Length1 + */ + public int getLength1() { + return this.headerSegment.length; + } + + + /** + * Returns the Length2 (length of the encrypted segment). + * @return int Length2 + */ + public int getLength2() { + return this.encryptedSegment.length; + } + + + /** + * Returns the Length3 (length of the trailer segment). + * @return int Length3 + */ + public int getLength3() { + return this.trailerSegment.length; + } + + + /** + * Writes the PFB file in raw format to an OutputStream. + * @param out the OutputStream to write to + * @throws IOException In case of an I/O problem + */ + public void outputAllParts(OutputStream out) throws IOException { + out.write(this.headerSegment); + out.write(this.encryptedSegment); + out.write(this.trailerSegment); + } + + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return "PFB: format=" + getPFBFormat() + + " len1=" + getLength1() + + " len2=" + getLength2() + + " len3=" + getLength3(); + } + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/type1/PFBParser.java b/src/java/org/apache/fop/fonts/type1/PFBParser.java new file mode 100644 index 000000000..f02fb5a15 --- /dev/null +++ b/src/java/org/apache/fop/fonts/type1/PFBParser.java @@ -0,0 +1,276 @@ +/* + * $Id: PFBParser.java,v 1.3 2003/03/06 17:43:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.type1; + +import java.io.IOException; +import java.io.InputStream; +import java.io.DataInputStream; +import java.io.BufferedInputStream; + +//FOP +import org.apache.fop.util.StreamUtilities; + +/** + * This class represents a parser for Adobe Type 1 PFB files. + * + * @see PFBData + */ +public class PFBParser { + + private static final byte[] CURRENTFILE_EEXEC; + private static final byte[] CLEARTOMARK; + + static { + try { + CURRENTFILE_EEXEC = "currentfile eexec".getBytes("US-ASCII"); + CLEARTOMARK = "cleartomark".getBytes("US-ASCII"); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException("Incompatible VM. It doesn't support the US-ASCII encoding"); + } + } + + + /** + * Parses a PFB file into a PFBData object. + * @param url URL to load the PFB file from + * @return PFBData memory representation of the font + * @throws IOException In case of an I/O problem + */ + public PFBData parsePFB(java.net.URL url) throws IOException { + InputStream in = url.openStream(); + try { + return parsePFB(in); + } finally { + in.close(); + } + } + + + /** + * Parses a PFB file into a PFBData object. + * @param pfbFile File to load the PFB file from + * @return PFBData memory representation of the font + * @throws IOException In case of an I/O problem + */ + public PFBData parsePFB(java.io.File pfbFile) throws IOException { + InputStream in = new java.io.FileInputStream(pfbFile); + try { + return parsePFB(in); + } finally { + in.close(); + } + } + + + /** + * Parses a PFB file into a PFBData object. + * @param in InputStream to load the PFB file from + * @return PFBData memory representation of the font + * @throws IOException In case of an I/O problem + */ + public PFBData parsePFB(InputStream in) throws IOException { + PFBData pfb = new PFBData(); + BufferedInputStream bin = new BufferedInputStream(in); + DataInputStream din = new DataInputStream(bin); + din.mark(32); + int firstByte = din.readUnsignedByte(); + din.reset(); + if (firstByte == 128) { + pfb.setPFBFormat(PFBData.PFB_PC); + parsePCFormat(pfb, din); + } else { + pfb.setPFBFormat(PFBData.PFB_RAW); + parseRAWFormat(pfb, bin); + } + return pfb; + } + + + private static int swapInteger(final int value) { + return (((value >> 0) & 0xff) << 24) + + (((value >> 8) & 0xff) << 16) + + (((value >> 16) & 0xff) << 8) + + (((value >> 24) & 0xff) << 0); + } + + + private void parsePCFormat(PFBData pfb, DataInputStream din) throws IOException { + int segmentHead; + int segmentType; + int bytesRead; + + //Read first segment + segmentHead = din.readUnsignedByte(); + if (segmentHead != 128) { + throw new IOException("Invalid file format. Expected ASCII 80hex"); + } + segmentType = din.readUnsignedByte(); //Read + int len1 = swapInteger(din.readInt()); + byte[] headerSegment = new byte[len1]; + bytesRead = din.read(headerSegment); + if (bytesRead != len1) { + throw new IOException("Could not load the whole segment"); + } + pfb.setHeaderSegment(headerSegment); + + //Read second segment + segmentHead = din.readUnsignedByte(); + if (segmentHead != 128) { + throw new IOException("Invalid file format. Expected ASCII 80hex"); + } + segmentType = din.readUnsignedByte(); + int len2 = swapInteger(din.readInt()); + byte[] encryptedSegment = new byte[len2]; + bytesRead = din.read(encryptedSegment); + if (bytesRead != len2) { + throw new IOException("Could not load the whole segment"); + } + pfb.setEncryptedSegment(encryptedSegment); + + //Read third segment + segmentHead = din.readUnsignedByte(); + if (segmentHead != 128) { + throw new IOException("Invalid file format. Expected ASCII 80hex"); + } + segmentType = din.readUnsignedByte(); + int len3 = swapInteger(din.readInt()); + byte[] trailerSegment = new byte[len3]; + bytesRead = din.read(trailerSegment); + if (bytesRead != len3) { + throw new IOException("Could not load the whole segment"); + } + pfb.setTrailerSegment(trailerSegment); + + //Read EOF indicator + segmentHead = din.readUnsignedByte(); + if (segmentHead != 128) { + throw new IOException("Invalid file format. Expected ASCII 80hex"); + } + segmentType = din.readUnsignedByte(); + if (segmentType != 3) { + throw new IOException("Expected segment type 3, but found: " + segmentType); + } + } + + + private static final boolean byteCmp(byte[] src, int srcOffset, byte[] cmp) { + for (int i = 0; i < cmp.length; i++) { + // System.out.println("Compare: " + src[srcOffset + i] + " " + cmp[i]); + if (src[srcOffset + i] != cmp[i]) { + return false; + } + } + return true; + } + + private void calcLengths(PFBData pfb, byte[] originalData) { + // Calculate length 1 and 3 + // System.out.println ("Checking font, size = "+originalData.length); + + // Length1 is the size of the initial ascii portion + // search for "currentfile eexec" + // Get the first binary number and search backwards for "eexec" + int len1 = 30; + + // System.out.println("Length1="+len1); + while (!byteCmp(originalData, len1 - CURRENTFILE_EEXEC.length, CURRENTFILE_EEXEC)) { + len1++; + } + + // Skip newline + len1++; + + // Length3 is length of the last portion of the file + int len3 = 0; + len3 -= CLEARTOMARK.length; + while (!byteCmp(originalData, originalData.length + len3, CLEARTOMARK)) { + len3--; + // System.out.println("Len3="+len3); + } + len3 = -len3; + len3++; + // Eat 512 zeroes + int numZeroes = 0; + byte[] ws1 = new byte[]{0x0D}; //CR + byte[] ws2 = new byte[]{0x0A}; //LF + byte[] ws3 = new byte[]{0x30}; //"0" + while ((originalData[originalData.length - len3] == ws1[0] + || originalData[originalData.length - len3] == ws2[0] + || originalData[originalData.length - len3] == ws3[0]) + && numZeroes < 512) { + len3++; + if (originalData[originalData.length - len3] == ws3[0]) { + numZeroes++; + } + } + // System.out.println("Length3="+len3); + + //Create the 3 segments + byte[] buffer = new byte[len1]; + System.arraycopy(originalData, 0, buffer, 0, len1); + pfb.setHeaderSegment(buffer); + + int len2 = originalData.length - len3 - len1; + buffer = new byte[len2]; + System.arraycopy(originalData, len1, buffer, 0, len2); + pfb.setEncryptedSegment(buffer); + + buffer = new byte[len3]; + System.arraycopy(originalData, len1 + len2, buffer, 0, len3); + pfb.setTrailerSegment(buffer); + } + + private void parseRAWFormat(PFBData pfb, BufferedInputStream bin) + throws IOException { + calcLengths(pfb, StreamUtilities.toByteArray(bin, 32768)); + } + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/type1/PFMFile.java b/src/java/org/apache/fop/fonts/type1/PFMFile.java new file mode 100644 index 000000000..caa01b474 --- /dev/null +++ b/src/java/org/apache/fop/fonts/type1/PFMFile.java @@ -0,0 +1,468 @@ +/* + * $Id: PFMFile.java,v 1.3 2003/03/06 17:43:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.type1; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +//Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; + +//FOP +import org.apache.fop.fonts.Glyphs; +import org.apache.fop.util.StreamUtilities; + +/** + * This class represents a PFM file (or parts of it) as a Java object. + */ +public class PFMFile extends AbstractLogEnabled { + + // Header stuff + private String windowsName; + private String postscriptName; + private short dfItalic; + private int dfWeight; + private short dfCharSet; + private short dfPitchAndFamily; + private int dfAvgWidth; + private int dfMaxWidth; + private int dfMinWidth; + private short dfFirstChar; + private short dfLastChar; + + // Extension stuff + // --- + + // Extend Text Metrics + private int etmCapHeight; + private int etmXHeight; + private int etmLowerCaseAscent; + private int etmLowerCaseDescent; + + // Extent table + private int[] extentTable; + + private Map kerningTab = new java.util.HashMap(); + + /** + * Parses a PFM file + * + * @param inStream The stream from which to read the PFM file. + * @throws IOException In case of an I/O problem + */ + public void load(InputStream inStream) throws IOException { + final byte[] buf = StreamUtilities.toByteArray(inStream, 8000); + final InputStream bufin = new java.io.ByteArrayInputStream(buf); + PFMInputStream in = new PFMInputStream(bufin); + /*final int version =*/ in.readShort(); + final long filesize = in.readInt(); + if (filesize != buf.length) { + getLogger().warn("Effective file size is not the same as indicated in the header."); + } + bufin.reset(); + + loadHeader(in); + loadExtension(in); + } + + /** + * Parses the header of the PFM file. + * + * @param inStream The stream from which to read the PFM file. + * @throws IOException In case of an I/O problem + */ + private void loadHeader(PFMInputStream inStream) throws IOException { + inStream.skip(80); + dfItalic = inStream.readByte(); + inStream.skip(2); + dfWeight = inStream.readShort(); + dfCharSet = inStream.readByte(); + inStream.skip(4); + dfPitchAndFamily = inStream.readByte(); + dfAvgWidth = inStream.readShort(); + dfMaxWidth = inStream.readShort(); + dfFirstChar = inStream.readByte(); + dfLastChar = inStream.readByte(); + inStream.skip(8); + long faceOffset = inStream.readInt(); + + inStream.reset(); + inStream.skip(faceOffset); + windowsName = inStream.readString(); + + inStream.reset(); + inStream.skip(117); + } + + /** + * Parses the extension part of the PFM file. + * + * @param inStream The stream from which to read the PFM file. + */ + private void loadExtension(PFMInputStream inStream) throws IOException { + final int size = inStream.readShort(); + if (size != 30) { + getLogger().warn("Size of extension block was expected to be " + + "30 bytes, but was " + size + " bytes."); + } + final long extMetricsOffset = inStream.readInt(); + final long extentTableOffset = inStream.readInt(); + inStream.skip(4); //Skip dfOriginTable + final long kernPairOffset = inStream.readInt(); + inStream.skip(4); //Skip dfTrackKernTable + long driverInfoOffset = inStream.readInt(); + + if (kernPairOffset > 0) { + inStream.reset(); + inStream.skip(kernPairOffset); + loadKernPairs(inStream); + } + + inStream.reset(); + inStream.skip(driverInfoOffset); + postscriptName = inStream.readString(); + + if (extMetricsOffset != 0) { + inStream.reset(); + inStream.skip(extMetricsOffset); + loadExtMetrics(inStream); + } + if (extentTableOffset != 0) { + inStream.reset(); + inStream.skip(extentTableOffset); + loadExtentTable(inStream); + } + + } + + /** + * Parses the kernPairs part of the pfm file + * + * @param inStream The stream from which to read the PFM file. + */ + private void loadKernPairs(PFMInputStream inStream) throws IOException { + int i = inStream.readShort(); + + + getLogger().info(i + " kerning pairs"); + while (i > 0) { + int g1 = (int)inStream.readByte(); + i--; + + int g2 = (int)inStream.readByte(); + + int adj = inStream.readShort(); + if (adj > 0x8000) { + adj = -(0x10000 - adj); + } + getLogger().debug("Char no: (" + g1 + ", " + g2 + ") kern: " + adj); + + if (getLogger().isDebugEnabled()) { + final String glyph1 = Glyphs.TEX8R_GLYPH_NAMES[g1]; + final String glyph2 = Glyphs.TEX8R_GLYPH_NAMES[g2]; + getLogger().debug("glyphs: " + glyph1 + ", " + glyph2); + } + + Map adjTab = (Map)kerningTab.get(new Integer(g1)); + if (adjTab == null) { + adjTab = new java.util.HashMap(); + } + adjTab.put(new Integer(g2), new Integer(adj)); + kerningTab.put(new Integer(g1), adjTab); + } + } + + /** + * Parses the extended metrics part of the PFM file. + * + * @param inStream The stream from which to read the PFM file. + */ + private void loadExtMetrics(PFMInputStream inStream) throws IOException { + final int size = inStream.readShort(); + if (size != 52) { + getLogger().warn("Size of extension block was expected to be " + + "52 bytes, but was " + size + " bytes."); + } + inStream.skip(12); //Skip etmPointSize, etmOrientation, etmMasterHeight, + //etmMinScale, etmMaxScale, emtMasterUnits + etmCapHeight = inStream.readShort(); + etmXHeight = inStream.readShort(); + etmLowerCaseAscent = inStream.readShort(); + etmLowerCaseDescent = inStream.readShort(); + //Ignore the rest of the values + } + + /** + * Parses the extent table of the PFM file. + * + * @param inStream The stream from which to read the PFM file. + */ + private void loadExtentTable(PFMInputStream inStream) throws IOException { + extentTable = new int[dfLastChar - dfFirstChar + 1]; + dfMinWidth = dfMaxWidth; + for (short i = dfFirstChar; i <= dfLastChar; i++) { + extentTable[i - dfFirstChar] = inStream.readShort(); + if (extentTable[i - dfFirstChar] < dfMinWidth) { + dfMinWidth = extentTable[i - dfFirstChar]; + } + } + } + + /** + * Returns the Windows name of the font. + * + * @return The Windows name. + */ + public String getWindowsName() { + return windowsName; + } + + /** + * Return the kerning table. The kerning table is a Map with + * strings with glyphnames as keys, containing Maps as value. + * The value map contains a glyph name string key and an Integer value + * + * @return A Map containing the kerning table + */ + public Map getKerning() { + return kerningTab; + } + + /** + * Returns the Postscript name of the font. + * + * @return The Postscript name. + */ + public String getPostscriptName() { + return postscriptName; + } + + /** + * Returns the charset used for the font. + * + * @return The charset (0=WinAnsi). + */ + public short getCharSet() { + return dfCharSet; + } + + /** + * Returns the charset of the font as a string. + * + * @return The name of the charset. + */ + public String getCharSetName() { + switch (dfCharSet) { + case 0: + return "WinAnsi"; + case 128: + return "Shift-JIS (Japanese)"; + default: + return "Unknown"; + } + } + + /** + * Returns the number of the character that defines + * the first entry in the widths list. + * + * @return The number of the first character. + */ + public short getFirstChar() { + return dfFirstChar; + } + + /** + * Returns the number of the character that defines + * the last entry in the widths list. + * + * @return The number of the last character. + */ + public short getLastChar() { + return dfLastChar; + } + + /** + * Returns the CapHeight parameter for the font (height of uppercase H). + * + * @return The CapHeight parameter. + */ + public int getCapHeight() { + return etmCapHeight; + } + + /** + * Returns the XHeight parameter for the font (height of lowercase x). + * + * @return The CapHeight parameter. + */ + public int getXHeight() { + return etmXHeight; + } + + /** + * Returns the LowerCaseAscent parameter for the font (height of lowercase d). + * + * @return The LowerCaseAscent parameter. + */ + public int getLowerCaseAscent() { + return etmLowerCaseAscent; + } + + /** + * Returns the LowerCaseDescent parameter for the font (height of lowercase p). + * + * @return The LowerCaseDescent parameter. + */ + public int getLowerCaseDescent() { + return etmLowerCaseDescent; + } + + /** + * Tells whether the font has proportional character spacing. + * + * @return ex. true for Times, false for Courier. + */ + public boolean getIsProportional() { + return ((dfPitchAndFamily & 1) == 1); + } + + /** + * Returns the bounding box for the font. + * Note: this value is just an approximation, + * it does not really exist in the PFM file. + * + * @return The calculated Font BBox. + */ + public int[] getFontBBox() { + int[] bbox = new int[4]; + + // Just guessing.... + if (!getIsProportional() && (dfAvgWidth == dfMaxWidth)) { + bbox[0] = -20; + } else { + bbox[0] = -100; + } + bbox[1] = -(getLowerCaseDescent() + 5); + bbox[2] = dfMaxWidth + 10; + bbox[3] = getLowerCaseAscent() + 5; + return bbox; + } + + /** + * Returns the characteristics flags for the font as + * needed for a PDF font descriptor (See PDF specs). + * + * @return The characteristics flags. + */ + public int getFlags() { + int flags = 0; + if (!getIsProportional()) { + flags |= 1; + } + if ((dfPitchAndFamily & 16) == 16) { + flags |= 2; + } + if ((dfPitchAndFamily & 64) == 64) { + flags |= 4; + } + if (dfCharSet == 0) { + flags |= 6; + } + if (dfItalic != 0) { + flags |= 7; + } + return flags; + } + + /** + * Returns the width of the dominant vertical stems of the font. + * Note: this value is just an approximation, + * it does not really exist in the PFM file. + * + * @return The vertical stem width. + */ + public int getStemV() { + // Just guessing.... + if (dfItalic != 0) { + return (int)Math.round(dfMinWidth * 0.25); + } else { + return (int)Math.round(dfMinWidth * 0.6); + } + } + + /** + * Returns the italic angle of the font. + * Note: this value is just an approximation, + * it does not really exist in the PFM file. + * + * @return The italic angle. + */ + public int getItalicAngle() { + if (dfItalic != 0) { + return -16; // Just guessing.... + } else { + return 0; + } + } + + /** + * Returns the width of a character + * + * @param which The number of the character for which the width is requested. + * @return The width of a character. + */ + public int getCharWidth(short which) { + return extentTable[which - dfFirstChar]; + } + +} diff --git a/src/java/org/apache/fop/fonts/type1/PFMInputStream.java b/src/java/org/apache/fop/fonts/type1/PFMInputStream.java new file mode 100644 index 000000000..a70f7e5df --- /dev/null +++ b/src/java/org/apache/fop/fonts/type1/PFMInputStream.java @@ -0,0 +1,139 @@ +/* + * $Id: PFMInputStream.java,v 1.3 2003/03/06 17:43:07 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.fonts.type1; + +import java.io.IOException; +import java.io.InputStream; +import java.io.DataInputStream; +import java.io.InputStreamReader; + +/** + * This is a helper class for reading PFM files. It defines functions for + * extracting specific values out of the stream. + */ +public class PFMInputStream extends java.io.FilterInputStream { + + private DataInputStream datain; + + /** + * Constructs a PFMInputStream based on an InputStream representing the + * PFM file. + * + * @param in The stream from which to read the PFM file + */ + public PFMInputStream(InputStream in) { + super(in); + datain = new DataInputStream(in); + } + + /** + * Parses a one byte value out of the stream. + * + * @return The value extracted + * @throws IOException In case of an I/O problem + */ + public short readByte() throws IOException { + short s = datain.readByte(); + // Now, we've got to trick Java into forgetting the sign + int s1 = (((s & 0xF0) >>> 4) << 4) + (s & 0x0F); + return (short)s1; + } + + /** + * Parses a two byte value out of the stream. + * + * @return The value extracted + * @throws IOException In case of an I/O problem + */ + public int readShort() throws IOException { + int i = datain.readShort(); + + // Change byte order + int high = (i & 0xFF00) >>> 8; + int low = (i & 0x00FF) << 8; + return low + high; + } + + /** + * Parses a four byte value out of the stream. + * + * @return The value extracted + * @throws IOException In case of an I/O problem + */ + public long readInt() throws IOException { + int i = datain.readInt(); + + // Change byte order + int i1 = (i & 0xFF000000) >>> 24; + int i2 = (i & 0x00FF0000) >>> 8; + int i3 = (i & 0x0000FF00) << 8; + int i4 = (i & 0x000000FF) << 24; + return i1 + i2 + i3 + i4; + } + + /** + * Parses a zero-terminated string out of the stream. + * + * @return The value extracted + * @throws IOException In case of an I/O problem + */ + public String readString() throws IOException { + InputStreamReader reader = new InputStreamReader(in, "ISO-8859-1"); + StringBuffer buf = new StringBuffer(); + int ch = reader.read(); + while (ch != 0) { + buf.append((char)ch); + ch = reader.read(); + } + return buf.toString(); + } + +} diff --git a/src/java/org/apache/fop/fonts/type1/package.html b/src/java/org/apache/fop/fonts/type1/package.html new file mode 100644 index 000000000..0c492fc4d --- /dev/null +++ b/src/java/org/apache/fop/fonts/type1/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.fonts.type1 Package + +

Classes for Adobe Type 1 fonts.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/image/AbstractFopImage.java b/src/java/org/apache/fop/image/AbstractFopImage.java new file mode 100644 index 000000000..775e6e054 --- /dev/null +++ b/src/java/org/apache/fop/image/AbstractFopImage.java @@ -0,0 +1,332 @@ +/* + * $Id: AbstractFopImage.java,v 1.17 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.io.InputStream; + +// FOP +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.fo.FOUserAgent; + +/** + * Base class to implement the FopImage interface. + * @author Eric SCHAEFFER + * @author Modified by Eric Dalquist - 9/14/2001 - ebdalqui@mtu.edu + * @see FopImage + */ +public abstract class AbstractFopImage implements FopImage { + /** + * Keeps track of what has been loaded. + */ + protected int loaded = 0; + + /** + * Image width (in pixel). + */ + protected int width = 0; + + /** + * Image height (in pixel). + */ + protected int height = 0; + + /** + * Image input stream. + */ + protected InputStream inputStream = null; + + /** + * ImageReader object (to obtain image header informations). + */ + protected FopImage.ImageInfo imageInfo = null; + + /** + * Image color space (java.awt.color.ColorSpace). + */ + protected ColorSpace colorSpace = null; + + /** + * Bits per pixel. + */ + protected int bitsPerPixel = 0; + + /** + * Image data (uncompressed). + */ + protected byte[] bitmaps = null; + + /** + * Image data size. + */ + protected int bitmapsSize = 0; + + /** + * Image transparency. + */ + protected boolean isTransparent = false; + + /** + * Transparent color (org.apache.fop.pdf.PDFColor). + */ + protected PDFColor transparentColor = null; + + /** + * Constructor. + * Construct a new FopImage object and initialize its default properties: + *
    + *
  • image width + *
  • image height + *
+ * The image data isn't kept in memory. + * @param info image information + */ + public AbstractFopImage(FopImage.ImageInfo info) { + this.inputStream = info.inputStream; + this.imageInfo = info; + if (this.imageInfo.width != -1) { + width = imageInfo.width; + height = imageInfo.height; + loaded = loaded | DIMENSIONS; + } + } + + /** + * Get the mime type for this image. + * + * @return the mime type for the image + */ + public String getMimeType() { + return imageInfo.mimeType; + } + + /** + * Load image data and initialize its properties. + * + * @param type the type of loading to do + * @param ua the user agent for handling logging etc. + * @return true if the loading was successful + */ + public synchronized boolean load(int type, FOUserAgent ua) { + if ((loaded & type) != 0) { + return true; + } + boolean success = true; + if (((type & DIMENSIONS) != 0) && ((loaded & DIMENSIONS) == 0)) { + success = success && loadDimensions(ua); + + if (!success) { + return false; + } + loaded = loaded | DIMENSIONS; + } + if (((type & BITMAP) != 0) && ((loaded & BITMAP) == 0)) { + success = success && loadBitmap(ua); + if (success) { + loaded = loaded | BITMAP; + } + } + if (((type & ORIGINAL_DATA) != 0) && ((loaded & ORIGINAL_DATA) == 0)) { + success = success && loadOriginalData(ua); + if (success) { + loaded = loaded | ORIGINAL_DATA; + } + } + return success; + } + + /** + * Load the dimensions of the image. + * All implementations should override this to get and + * return the dimensions. + * + * @param ua the user agent + * @return true if the loading was successful + */ + protected boolean loadDimensions(FOUserAgent ua) { + return false; + } + + /** + * Load a bitmap array of the image. + * If the renderer requires a bitmap image then the + * implementations should override this to load the bitmap. + * + * @param ua the user agent + * @return true if the loading was successful + */ + protected boolean loadBitmap(FOUserAgent ua) { + return false; + } + + /** + * Load the original image data. + * In some cases the original data can be used by the renderer. + * This should load the data and any other associated information. + * + * @param ua the user agent + * @return true if the loading was successful + */ + protected boolean loadOriginalData(FOUserAgent ua) { + return false; + } + + /** + * Return the image width. + * @return the image width + */ + public int getWidth() { + return this.width; + } + + /** + * Return the image height. + * @return the image height + */ + public int getHeight() { + return this.height; + } + + /** + * Return the image color space. + * @return the image color space (java.awt.color.ColorSpace) + */ + public ColorSpace getColorSpace() { + return this.colorSpace; + } + + /** + * Get ICC profile for this image. + * @return the icc profile or null if not applicable + */ + public ICC_Profile getICCProfile() { + return null; + } + + /** + * Return the number of bits per pixel. + * @return number of bits per pixel + */ + public int getBitsPerPixel() { + return this.bitsPerPixel; + } + + /** + * Return the image transparency. + * @return true if the image is transparent + */ + public boolean isTransparent() { + return this.isTransparent; + } + + /** + * Check if this image has a soft mask. + * + * @return true if the image also has a soft transparency mask + */ + public boolean hasSoftMask() { + return false; + } + + /** + * Get the soft mask. + * The soft mask should have the same bitdepth as the image data. + * + * @return the data array of soft mask values + */ + public byte[] getSoftMask() { + return null; + } + + /** + * Return the transparent color. + * @return the transparent color (org.apache.fop.pdf.PDFColor) + */ + public PDFColor getTransparentColor() { + return this.transparentColor; + } + + /** + * Return the image data (uncompressed). + * @return the image data + */ + public byte[] getBitmaps() { + return this.bitmaps; + } + + /** + * Return the image data size (uncompressed). + * @return the image data size + */ + public int getBitmapsSize() { + return this.bitmapsSize; + } + + /** + * Return the original image data (compressed). + * @return the original image data + */ + public byte[] getRessourceBytes() { + return null; + } + + /** + * Return the original image data size (compressed). + * @return the original image data size + */ + public int getRessourceBytesSize() { + return 0; + } + +} + diff --git a/src/java/org/apache/fop/image/BmpImage.java b/src/java/org/apache/fop/image/BmpImage.java new file mode 100644 index 000000000..58b4607a8 --- /dev/null +++ b/src/java/org/apache/fop/image/BmpImage.java @@ -0,0 +1,255 @@ +/* + * $Id: BmpImage.java,v 1.10 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.io.IOException; +import java.awt.color.ColorSpace; + +// FOP +import org.apache.fop.fo.FOUserAgent; + +/** + * Bitmap image. + * This supports loading a bitmap image into bitmap data. + * + * @author Art WELCH + * @see AbstractFopImage + * @see FopImage + */ +public class BmpImage extends AbstractFopImage { + /** + * Create a bitmap image with the image data. + * + * @param imgInfo the image information + */ + public BmpImage(FopImage.ImageInfo imgInfo) { + super(imgInfo); + } + + /** + * Load the bitmap. + * This laods the bitmap data from the bitmap image. + * + * @param ua the user agent + * @return true if it was loaded successfully + */ + protected boolean loadBitmap(FOUserAgent ua) { + int wpos = 18; + int hpos = 22; // offset positioning for w and height in bmp files + int[] headermap = new int[54]; + int filepos = 0; + byte palette[] = null; + try { + boolean eof = false; + while ((!eof) && (filepos < 54)) { + int input = inputStream.read(); + if (input == -1) { + eof = true; + } else { + headermap[filepos++] = input; + } + } + + if (headermap[28] == 4 || headermap[28] == 8) { + int palettesize = 1 << headermap[28]; + palette = new byte[palettesize * 3]; + int countr = 0; + while (!eof && countr < palettesize) { + int count2 = 2; + while (!eof && count2 >= -1) { + int input = inputStream.read(); + if (input == -1) { + eof = true; + } else if (count2 >= 0) { + palette[countr * 3 + count2] = + (byte)(input & 0xFF); + } + count2--; + filepos++; + } + countr++; + } + } + } catch (IOException e) { + ua.getLogger().error("Error while loading image " + + "" + " : " + + e.getClass() + " - " + + e.getMessage(), e); + return false; + } + // gets h & w from headermap + this.width = headermap[wpos] + + headermap[wpos + 1] * 256 + + headermap[wpos + 2] * 256 * 256 + + headermap[wpos + 3] * 256 * 256 * 256; + this.height = headermap[hpos] + + headermap[hpos + 1] * 256 + + headermap[hpos + 2] * 256 * 256 + + headermap[hpos + 3] * 256 * 256 * 256; + + int imagestart = headermap[10] + + headermap[11] * 256 + + headermap[12] * 256 * 256 + + headermap[13] * 256 * 256 * 256; + this.bitsPerPixel = headermap[28]; + this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + int bytes = 0; + if (this.bitsPerPixel == 1) { + bytes = (this.width + 7) / 8; + } else if (this.bitsPerPixel == 24) { + bytes = this.width * 3; + } else if (this.bitsPerPixel == 4 || this.bitsPerPixel == 8) { + bytes = this.width / (8 / this.bitsPerPixel); + } else { + ua.getLogger().error("Image (" + "" + + ") has " + this.bitsPerPixel + + " which is not a supported BMP format."); + return false; + } + if ((bytes & 0x03) != 0) { + bytes |= 0x03; + bytes++; + } + + // Should take care of the ColorSpace and bitsPerPixel + this.bitmapsSize = this.width * this.height * 3; + this.bitmaps = new byte[this.bitmapsSize]; + + int[] temp = new int[bytes * this.height]; + try { + int input; + int count = 0; + inputStream.skip((long)(imagestart - filepos)); + while ((input = inputStream.read()) != -1) { + temp[count++] = input; + } + inputStream.close(); + inputStream = null; + } catch (IOException e) { + ua.getLogger().error("Error while loading image " + + "" + " : " + + e.getClass() + " - " + + e.getMessage(), e); + return false; + } + + for (int i = 0; i < this.height; i++) { + int x = 0; + int j = 0; + while (j < bytes) { + int p = temp[(this.height - i - 1) * bytes + j]; + + if (this.bitsPerPixel == 24 && x < this.width) { + int countr = 2; + do { + this.bitmaps[3 * (i * this.width + x) + countr] = + (byte)(temp[(this.height - i - 1) + * bytes + j] & 0xFF); + j++; + } while (--countr >= 0) + ; + x++; + } else if (this.bitsPerPixel == 1) { + for (int countr = 0; + countr < 8 && x < this.width; countr++) { + if ((p & 0x80) != 0) { + this.bitmaps[3 * (i * this.width + x)] = (byte) 0xFF; + this.bitmaps[3 * (i * this.width + x) + 1] = (byte) 0xFF; + this.bitmaps[3 * (i * this.width + x) + 2] = (byte) 0xFF; + } else { + this.bitmaps[3 * (i * this.width + x)] = (byte) 0; + this.bitmaps[3 * (i * this.width + x) + 1] = (byte) 0; + this.bitmaps[3 * (i * this.width + x) + 2] = (byte) 0; + } + p <<= 1; + x++; + } + j++; + } else if (this.bitsPerPixel == 4) { + for (int countr = 0; + countr < 2 && x < this.width; countr++) { + int pal = ((p & 0xF0) >> 4) * 3; + this.bitmaps[3 * (i * this.width + x)] = palette[pal]; + this.bitmaps[3 * (i * this.width + x) + 1] = palette[pal + 1]; + this.bitmaps[3 * (i * this.width + x) + 2] = palette[pal + 2]; + p <<= 4; + x++; + } + j++; + } else if (this.bitsPerPixel == 8) { + if (x < this.width) { + p *= 3; + this.bitmaps[3 * (i * this.width + x)] = palette[p]; + this.bitmaps[3 * (i * this.width + x) + 1] = palette[p + 1]; + this.bitmaps[3 * (i * this.width + x) + 2] = palette[p + 2]; + j++; + x++; + } else { + j = bytes; + } + } else { + j++; + } + } + } + + // This seems really strange to me, but I noticed that + // JimiImage hardcodes bitsPerPixel to 8. If I do not + // do this Acrobat is unable to read the resultant PDF, + // so we will hardcode this... + this.bitsPerPixel = 8; + + return true; + } + +} + diff --git a/src/java/org/apache/fop/image/EPSImage.java b/src/java/org/apache/fop/image/EPSImage.java new file mode 100644 index 000000000..23d4d8ca9 --- /dev/null +++ b/src/java/org/apache/fop/image/EPSImage.java @@ -0,0 +1,153 @@ +/* + * $Id: EPSImage.java,v 1.11 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + + +/** + * EPS image handler. + * This handles the Encapulated PostScript images. + * It gets the dimensions and original data from the analyser. + * + * @see AbstractFopImage + * @see FopImage + */ +public class EPSImage extends AbstractFopImage { + + private String docName; + private int[] bbox; + + private EPSData epsData = null; + + /** + * Create an EPS image with the image information. + * + * @param imgInfo the information containing the data and bounding box + */ + public EPSImage(FopImage.ImageInfo imgInfo) { + super(imgInfo); + init(""); + if (imgInfo.data instanceof EPSData) { + epsData = (EPSData) imgInfo.data; + bbox = new int[4]; + bbox[0] = (int) epsData.bbox[0]; + bbox[1] = (int) epsData.bbox[1]; + bbox[2] = (int) epsData.bbox[2]; + bbox[3] = (int) epsData.bbox[3]; + + loaded = loaded | ORIGINAL_DATA; + } + } + + /** + * Initialize docName and bounding box. + * @param name the document name + */ + private void init(String name) { + bbox = new int[4]; + bbox[0] = 0; + bbox[1] = 0; + bbox[2] = 0; + bbox[3] = 0; + + docName = name; + } + + /** + * Return the name of the eps + * @return the name of the eps + */ + public String getDocName() { + return docName; + } + + /** + * Return the bounding box + * @return an int array containing the bounding box + */ + public int[] getBBox() { + return bbox; + } + + /** + * Get the eps image. + * + * @return the original eps image data + */ + public byte[] getEPSImage() { + if (epsData.epsFile == null) { + //log.error("ERROR LOADING EXTERNAL EPS"); + } + return epsData.epsFile; + } + + /** + * Data for EPS image. + */ + public static class EPSData { + public long[] bbox; + public boolean isAscii; // True if plain ascii eps file + + // offsets if not ascii + public long psStart = 0; + public long psLength = 0; + public long wmfStart = 0; + public long wmfLength = 0; + public long tiffStart = 0; + public long tiffLength = 0; + + /** raw eps file */ + public byte[] rawEps; + /** eps part */ + public byte[] epsFile; + public byte[] preview = null; + } + +} diff --git a/src/java/org/apache/fop/image/FopImage.java b/src/java/org/apache/fop/image/FopImage.java new file mode 100644 index 000000000..9dde72663 --- /dev/null +++ b/src/java/org/apache/fop/image/FopImage.java @@ -0,0 +1,196 @@ +/* + * $Id: FopImage.java,v 1.15 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +import java.io.InputStream; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; + +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.fo.FOUserAgent; + +/** + * Fop image interface for loading images. + * + * @author Eric SCHAEFFER + */ +public interface FopImage { + /** + * Flag for loading dimensions. + */ + public static final int DIMENSIONS = 1; + + /** + * Flag for loading original data. + */ + public static final int ORIGINAL_DATA = 2; + + /** + * Flag for loading bitmap data. + */ + public static final int BITMAP = 4; + + /** + * Get the mime type of this image. + * This is used so that when reading from the image it knows + * what type of image it is. + * + * @return the mime type string + */ + String getMimeType(); + + /** + * Load particular inforamtion for this image + * This must be called before attempting to get + * the information. + * + * @param type the type of loading required + * @param ua the user agent + * @return boolean true if the information could be loaded + */ + boolean load(int type, FOUserAgent ua); + + /** + * Returns the image width. + * @return the width in pixels + */ + int getWidth(); + + /** + * Returns the image height. + * @return the height in pixels + */ + int getHeight(); + + /** + * Returns the color space of the image. + * @return the color space + */ + ColorSpace getColorSpace(); + + /** + * Returns the ICC profile. + * @return the ICC profile, null if none is available + */ + ICC_Profile getICCProfile(); + + /** + * Returns the number of bits per pixel for the image. + * @return the number of bits per pixel + */ + int getBitsPerPixel(); + + /** + * Indicates whether the image is transparent. + * @return True if it is transparent + */ + boolean isTransparent(); + + /** + * For transparent images. Returns the transparent color. + * @return the transparent color + * @todo Remove the PDF dependency + */ + PDFColor getTransparentColor(); + + /** + * Indicates whether the image has a Soft Mask (See section 7.5.4 in the + * PDF specs) + * @return True if a Soft Mask exists + */ + boolean hasSoftMask(); + + /** + * For images with a Soft Mask. Returns the Soft Mask as an array. + * @return the Soft Mask + */ + byte[] getSoftMask(); + + /** + * Returns the decoded and uncompressed image as a array of + * width * height * [colorspace-multiplicator] pixels. + * @return the bitmap + */ + byte[] getBitmaps(); + /** + * Returns the size of the image. + * width * (bitsPerPixel / 8) * height, no ? + * @return the size + */ + int getBitmapsSize(); + + /** + * Returns the encoded/compressed image as an array of bytes. + * @return the raw image + */ + byte[] getRessourceBytes(); + + /** + * Returns the number of bytes of the raw image. + * @return the size in bytes + */ + int getRessourceBytesSize(); + + /** + * Image info class. + * Information loaded from analyser and passed to image object. + */ + public static class ImageInfo { + public InputStream inputStream; + public int width; + public int height; + public Object data; + public String mimeType; + public String str; + } + +} + diff --git a/src/java/org/apache/fop/image/FopImageConsumer.java b/src/java/org/apache/fop/image/FopImageConsumer.java new file mode 100644 index 000000000..2766a5657 --- /dev/null +++ b/src/java/org/apache/fop/image/FopImageConsumer.java @@ -0,0 +1,243 @@ +/* + * $Id: FopImageConsumer.java,v 1.9 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.util.Hashtable; +import java.awt.image.ColorModel; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageProducer; +import java.awt.image.PixelGrabber;; + +/** + * ImageConsumer implementation for FopImage classes. + * @author Eric SCHAEFFER + */ +public class FopImageConsumer implements ImageConsumer { + + /** Image width in pixels */ + protected int width = -1; + /** Image height in pixels */ + protected int height = -1; + /** Image status */ + protected Integer imageStatus = new Integer(-1); + /** hints */ + protected int hints = 0; + /** Image properties */ + protected Hashtable properties = null; + /** Color model */ + protected ColorModel cm = null; + /** Image producer */ + protected ImageProducer ip = null; + + /** + * Main constructor + * @param iprod ImageProducer to use + */ + public FopImageConsumer(ImageProducer iprod) { + this.ip = iprod; + } + + /** + * @see java.awt.image.ImageConsumer#imageComplete(int) + */ + public void imageComplete(int status) { + /* + * log.error("Status "); + * if (status == ImageConsumer.COMPLETESCANLINES) { + * log.error("CompleteScanLines"); + * } else if (status == ImageConsumer.IMAGEABORTED) { + * log.error("ImageAborted"); + * } else if (status == ImageConsumer.IMAGEERROR) { + * log.error("ImageError"); + * } else if (status == ImageConsumer.RANDOMPIXELORDER) { + * log.error("RandomPixelOrder"); + * } else if (status == ImageConsumer.SINGLEFRAME) { + * log.error("SingleFrame"); + * } else if (status == ImageConsumer.SINGLEFRAMEDONE) { + * log.error("SingleFrameDone"); + * } else if (status == ImageConsumer.SINGLEPASS) { + * log.error("SinglePass"); + * } else if (status == ImageConsumer.STATICIMAGEDONE) { + * log.error("StaticImageDone"); + * } else if (status == ImageConsumer.TOPDOWNLEFTRIGHT) { + * log.error("TopDownLeftRight"); + * } + */ + synchronized (this.imageStatus) { + // Need to stop status if image done + if (imageStatus.intValue() != ImageConsumer.STATICIMAGEDONE + && imageStatus.intValue() != ImageConsumer.SINGLEFRAMEDONE) { + this.imageStatus = new Integer(status); + } + } + } + + /** + * @see java.awt.image.ImageConsumer#setColorModel(ColorModel) + */ + public void setColorModel(ColorModel model) { + // log.error("setColorModel: " + model); + this.cm = model; + } + + /** + * @see java.awt.image.ImageConsumer#setDimensions(int, int) + */ + public void setDimensions(int width, int height) { + // log.error("setDimension: w=" + width + " h=" + height); + this.width = width; + this.height = height; + } + + /** + * @see java.awt.image.ImageConsumer#setHints(int) + */ + public void setHints(int hintflags) { + // log.error("setHints: " + hintflags); + this.hints = hintflags; + } + + /** + * @see java.awt.image.ImageConsumer#setProperties(Hashtable) + */ + public void setProperties(Hashtable props) { + // log.error("setProperties: " + props); + this.properties = props; + } + + /** + * @see java.awt.image.ImageConsumer#setPixels(int, int, int, int, ColorModel, byte[], int, int) + */ + public void setPixels(int x, int y, int w, int h, ColorModel model, + byte[] pixels, int off, int scansize) { + } + + /** + * @see java.awt.image.ImageConsumer#setPixels(int, int, int, int, ColorModel, int[], int, int) + */ + public void setPixels(int x, int y, int w, int h, ColorModel model, + int[] pixels, int off, int scansize) { + } + + /** + * Indicates whether the image is ready. + * @return boolean True if the image is ready, false if it's still loading + * @throws Exception If an error happened while loading the image + */ + public boolean isImageReady() throws Exception { + /**@todo Use a better exception than Exception */ + synchronized (this.imageStatus) { + if (this.imageStatus.intValue() == ImageConsumer.IMAGEABORTED) { + throw new Exception("Image aborted"); + } + if (this.imageStatus.intValue() == ImageConsumer.IMAGEERROR) { + throw new Exception("Image error"); + } + + if (imageStatus.intValue() == ImageConsumer.STATICIMAGEDONE + || imageStatus.intValue() == ImageConsumer.SINGLEFRAMEDONE) { + return true; + } + + return false; + } + } + + /** + * Returns the image width + * @return the width in pixels + */ + public int getWidth() { + return this.width; + } + + /** + * Returns the image height + * @return the height in pixels + */ + public int getHeight() { + return this.height; + } + + /** + * Returns the color model of the image + * @return the color model + */ + public ColorModel getColorModel() { + return this.cm; + } + + /** + * Returns the bitmap as an array. + * @return the bitmap as an array. + * @throws Exception if an error occured while generating the array + */ + public int[] getImage() throws Exception { + int tmpMap[] = new int[this.width * this.height]; + PixelGrabber pg = new PixelGrabber(this.ip, 0, 0, this.width, + this.height, tmpMap, 0, this.width); + pg.setDimensions(this.width, this.height); + pg.setColorModel(this.cm); + pg.setHints(this.hints); + pg.setProperties(this.properties); + try { + pg.grabPixels(); + } catch (InterruptedException intex) { + /**@todo Use a better exception than Exception */ + throw new Exception("Image grabbing interrupted : " + + intex.getMessage()); + } + return tmpMap; + } + +} + diff --git a/src/java/org/apache/fop/image/GifImage.java b/src/java/org/apache/fop/image/GifImage.java new file mode 100644 index 000000000..70b57b71f --- /dev/null +++ b/src/java/org/apache/fop/image/GifImage.java @@ -0,0 +1,241 @@ +/* + * $Id: GifImage.java,v 1.8 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.awt.image.ImageProducer; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.color.ColorSpace; +import java.io.InputStream; +import java.io.IOException; +import java.net.URLConnection; + +// FOP +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.fo.FOUserAgent; + +/** + * FopImage object for GIF images, using Java native classes. + * @author Eric SCHAEFFER + * @author Modified by Eric Dalquist - 9/14/2001 - ebdalqui@mtu.edu + * @see AbstractFopImage + * @see FopImage + */ +public class GifImage extends AbstractFopImage { + /** + * Create a new gif image. + * + * @param imgInfo the image info for this gif image + */ + public GifImage(FopImage.ImageInfo imgInfo) { + super(imgInfo); + } + + /** + * Load the bitmap for this gif image. + * This loads the data and creates a bitmap byte array + * of the image data. + * To decode the image a dummy URLConnection is used that + * will do the conversion. + * + * @param ua the user agent for loading + * @return True if the load process succeeded + */ + protected boolean loadBitmap(FOUserAgent ua) { + int[] tmpMap = null; + try { + URLConnection con = new DummyConnection(inputStream); + + ImageProducer ip = (ImageProducer) con.getContent(); + if (ip == null) { + return false; + } + FopImageConsumer consumer = new FopImageConsumer(ip); + ip.startProduction(consumer); + + //Load the image into memory + while (!consumer.isImageReady()) { + Thread.sleep(500); + } + + this.height = consumer.getHeight(); + this.width = consumer.getWidth(); + + try { + tmpMap = consumer.getImage(); + } catch (Exception ex) { + ua.getLogger().error("Image grabbing interrupted : " + + ex.getMessage(), ex); + return false; + } + + inputStream.close(); + inputStream = null; + + ColorModel cm = consumer.getColorModel(); + this.bitsPerPixel = 8; + // this.bitsPerPixel = cm.getPixelSize(); + this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + if (cm.hasAlpha()) { + // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); + + if (transparencyType == java.awt.Transparency.OPAQUE) { + this.isTransparent = false; + } else if (transparencyType == java.awt.Transparency.BITMASK) { + if (cm instanceof IndexColorModel) { + IndexColorModel indexcm = (IndexColorModel) cm; + this.isTransparent = false; + byte[] alphas = new byte[indexcm.getMapSize()]; + byte[] reds = new byte[indexcm.getMapSize()]; + byte[] greens = new byte[indexcm.getMapSize()]; + byte[] blues = new byte[indexcm.getMapSize()]; + indexcm.getAlphas(alphas); + indexcm.getReds(reds); + indexcm.getGreens(greens); + indexcm.getBlues(blues); + for (int i = 0; + i < indexcm.getMapSize(); + i++) { + if ((alphas[i] & 0xFF) == 0) { + this.isTransparent = true; + this.transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); + break; + } + } + } else { + // TRANSLUCENT + /* + * this.isTransparent = false; + * for (int i = 0; i < this.width * this.height; i++) { + * if (cm.getAlpha(tmpMap[i]) == 0) { + * this.isTransparent = true; + * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]), + * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); + * break; + * } + * } + */ + // use special API... + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + } catch (Exception ex) { + ua.getLogger().error("Error while loading image " + + "" + " : " + + ex.getClass() + " - " + + ex.getMessage(), ex); + return false; + } + + // Should take care of the ColorSpace and bitsPerPixel + this.bitmapsSize = this.width * this.height * 3; + this.bitmaps = new byte[this.bitmapsSize]; + for (int i = 0; i < this.height; i++) { + for (int j = 0; j < this.width; j++) { + int p = tmpMap[i * this.width + j]; + int r = (p >> 16) & 0xFF; + int g = (p >> 8) & 0xFF; + int b = (p) & 0xFF; + this.bitmaps[3 * (i * this.width + j)] = + (byte)(r & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 1] = + (byte)(g & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 2] = + (byte)(b & 0xFF); + } + } + return true; + } + + /** + * A dummy url connection for a gif image in an input stream. + */ + protected static class DummyConnection extends URLConnection { + private InputStream inputStream; + + DummyConnection(InputStream is) { + super(null); + inputStream = is; + } + + public InputStream getInputStream() throws IOException { + return inputStream; + } + + public void connect() throws IOException { + // do nothing + } + + public String getContentType() { + return "image/gif"; + } + + public int getContentLength() { + try { + return inputStream.available(); + } catch (IOException e) { + return -1; + } + } + + } +} + diff --git a/src/java/org/apache/fop/image/ImageCache.java b/src/java/org/apache/fop/image/ImageCache.java new file mode 100644 index 000000000..2b28afaa2 --- /dev/null +++ b/src/java/org/apache/fop/image/ImageCache.java @@ -0,0 +1,96 @@ +/* + * $Id: ImageCache.java,v 1.4 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// FOP +import org.apache.fop.fo.FOUserAgent; + +/** + * Image cache holder. + * This interface is used for caching images. + */ +public interface ImageCache { + /** + * Get an image from the cache. + * + * @param url the url and key for the image + * @param context the user agent context + * @return the requested image + */ + FopImage getImage(String url, FOUserAgent context); + + /** + * Release an image in the current context. + * + * @param url the url and key for the image + * @param context the user agent context + */ + void releaseImage(String url, FOUserAgent context); + + /** + * Invalidate image. + * If during loading this image is found to be invalid + * it will be invalidated to prevent further attempts at + * loading the image. + * + * @param url the url and key for the image + * @param context the user agent context + */ + void invalidateImage(String url, FOUserAgent context); + + /** + * Remove a context and handle all images in the context. + * + * @param context the user agent context + */ + void removeContext(FOUserAgent context); +} + diff --git a/src/java/org/apache/fop/image/ImageFactory.java b/src/java/org/apache/fop/image/ImageFactory.java new file mode 100644 index 000000000..2707afca6 --- /dev/null +++ b/src/java/org/apache/fop/image/ImageFactory.java @@ -0,0 +1,541 @@ +/* + * $Id: ImageFactory.java,v 1.15 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.MalformedURLException; +import java.lang.reflect.Constructor; +import java.util.Map; +import java.util.Set; +import java.util.Collections; +import java.util.Iterator; + +// Avalon +import org.apache.avalon.framework.logger.Logger; + +// FOP +import org.apache.fop.image.analyser.ImageReaderFactory; +import org.apache.fop.fo.FOUserAgent; + + +/** + * Create FopImage objects (with a configuration file - not yet implemented). + * @author Eric SCHAEFFER + */ +public class ImageFactory { + + private static ImageFactory factory = new ImageFactory(); + + private ImageCache cache = new ContextImageCache(true); + + private ImageFactory() { + } + + /** + * Get static image factory instance. + * + * @return the image factory instance + */ + public static ImageFactory getInstance() { + return factory; + } + + /** + * Get the url string from a wrapped url. + * + * @param href the input wrapped url + * @return the raw url + */ + public static String getURL(String href) { + /* + * According to section 5.11 a is: + * "url(" + URI + ")" + * according to 7.28.7 a is: + * URI + * So handle both. + */ + href = href.trim(); + if (href.startsWith("url(") && (href.indexOf(")") != -1)) { + href = href.substring(4, href.indexOf(")")).trim(); + if (href.startsWith("'") && href.endsWith("'")) { + href = href.substring(1, href.length() - 1); + } else if (href.startsWith("\"") && href.endsWith("\"")) { + href = href.substring(1, href.length() - 1); + } + } else { + // warn + } + return href; + } + + /** + * Get the image from the cache or load. + * If this returns null then the image could not be loaded + * due to an error. Messages should be logged. + * Before calling this the getURL(url) must be used. + * + * @param url the url for the image + * @param context the user agent context + * @return the fop image instance + */ + public FopImage getImage(String url, FOUserAgent context) { + return cache.getImage(url, context); + } + + /** + * Release an image from the cache. + * This can be used if the renderer has its own cache of + * the image. + * The image should then be put into the weak cache. + * + * @param url the url for the image + * @param context the user agent context + */ + public void releaseImage(String url, FOUserAgent context) { + cache.releaseImage(url, context); + } + + /** + * Release the context and all images in the context. + * + * @param context the context to remove + */ + public void removeContext(FOUserAgent context) { + cache.removeContext(context); + } + + /** + * Create an FopImage objects. + * @param href the url for the image + * @param ua the user agent context + * @return the fop image instance + */ + protected static FopImage loadImage(String href, FOUserAgent ua) { + Logger log = ua.getLogger(); + + InputStream in = openStream(href, ua); + + if (in == null) { + return null; + } + + // If not, check image type + FopImage.ImageInfo imgInfo = null; + try { + imgInfo = ImageReaderFactory.make( + href, in, ua); + } catch (Exception e) { + log.error("Error while recovering image information (" + + href + ") : " + e.getMessage(), e); + return null; + } + if (imgInfo == null) { + try { + in.close(); + in = null; + } catch (Exception e) { + log.debug("Error closing the InputStream for the image", e); + } + log.error("No ImageReader for this type of image (" + + href + ")"); + return null; + } + // Associate mime-type to FopImage class + String imgMimeType = imgInfo.mimeType; + String imgClassName = getImageClassName(imgMimeType); + if (imgClassName == null) { + log.error("Unsupported image type (" + + href + "): " + imgMimeType); + return null; + } + + // load the right image class + // return new + Object imageInstance = null; + Class imageClass = null; + try { + imageClass = Class.forName(imgClassName); + Class[] imageConstructorParameters = new Class[1]; + imageConstructorParameters[0] = org.apache.fop.image.FopImage.ImageInfo.class; + Constructor imageConstructor = + imageClass.getDeclaredConstructor( + imageConstructorParameters); + Object[] initArgs = new Object[1]; + initArgs[0] = imgInfo; + imageInstance = imageConstructor.newInstance(initArgs); + } catch (java.lang.reflect.InvocationTargetException ex) { + Throwable t = ex.getTargetException(); + String msg; + if (t != null) { + msg = t.getMessage(); + } else { + msg = ex.getMessage(); + } + log.error("Error creating FopImage object (" + + href + "): " + msg, (t == null) ? ex : t); + return null; + } catch (Exception ex) { + log.error("Error creating FopImage object (" + + href + "): " + ex.getMessage(), ex); + return null; + } + if (!(imageInstance instanceof org.apache.fop.image.FopImage)) { + log.error("Error creating FopImage object (" + + href + "): " + "class " + + imageClass.getName() + + " doesn't implement org.apache.fop.image.FopImage interface"); + return null; + } + return (FopImage) imageInstance; + } + + /** + * Create an FopImage objects. + * @param href image URL as a String + * @param ua user agent + * @return a new FopImage object + */ + protected static InputStream openStream(String href, FOUserAgent ua) { + Logger log = ua.getLogger(); + // Get the absolute URL + URL absoluteURL = null; + InputStream in = null; + try { + in = ua.getStream(href); + } catch (IOException ioe) { + log.error("Error while opening stream for (" + + href + "): " + ioe.getMessage(), ioe); + return null; + } + if (in == null) { + try { + // try url as complete first, this can cause + // a problem with relative uri's if there is an + // image relative to where fop is run and relative + // to the base dir of the document + try { + absoluteURL = new URL(href); + } catch (MalformedURLException mue) { + // if the href contains only a path then file is assumed + absoluteURL = new URL("file:" + href); + } + in = absoluteURL.openStream(); + } catch (MalformedURLException mfue) { + log.error("Error with image URL: " + mfue.getMessage(), mfue); + return null; + } catch (Exception e) { + // maybe relative + if (ua.getBaseURL() == null) { + log.error("Error with image URL: " + e.getMessage() + + " and no base URL is specified", e); + return null; + } + try { + absoluteURL = new URL(ua.getBaseURL() + absoluteURL.getFile()); + } catch (MalformedURLException e_context) { + // pb context url + log.error("Invalid Image URL - error on relative URL: " + + e_context.getMessage(), e_context); + return null; + } + } + } /* if (in == null) */ + + try { + if (in == null && absoluteURL != null) { + in = absoluteURL.openStream(); + } + if (in == null) { + log.error("Could not resolve URI for image: " + href); + return null; + } + + //Decorate the InputStream with a BufferedInputStream + return new java.io.BufferedInputStream(in); + } catch (Exception e) { + log.error("Error while opening stream for (" + + href + "): " + e.getMessage(), e); + return null; + } + } + + private static String getImageClassName(String imgMimeType) { + String imgClassName = null; + if ("image/gif".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.GifImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/jpeg".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JpegImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/bmp".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.BmpImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/eps".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.EPSImage"; + } else if ("image/png".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/tga".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/tiff".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.JimiImage"; + // imgClassName = "org.apache.fop.image.JAIImage"; + } else if ("image/svg+xml".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.XMLImage"; + } else if ("text/xml".equals(imgMimeType)) { + imgClassName = "org.apache.fop.image.XMLImage"; + } + return imgClassName; + } +} + +/** + * Basic image cache. + * This keeps track of invalid images. + */ +class BasicImageCache implements ImageCache { + + private Set invalid = Collections.synchronizedSet(new java.util.HashSet()); + private Map contextStore = Collections.synchronizedMap(new java.util.HashMap()); + + public FopImage getImage(String url, FOUserAgent context) { + if (invalid.contains(url)) { + return null; + } + return null; + } + + public void releaseImage(String url, FOUserAgent context) { + // do nothing + } + + public void invalidateImage(String url, FOUserAgent context) { + // cap size of invalid list + if (invalid.size() > 100) { + invalid.clear(); + } + invalid.add(url); + } + + public void removeContext(FOUserAgent context) { + // do nothing + } +} + +/** + * This is the context image cache. + * This caches images on the basis of the given context. + * Common images in different contexts are currently not handled. + * There are two possiblities, each context handles its own images + * and renderers can cache information or images are shared and + * all information is retained. + * Once a context is removed then all images are placed into a + * weak hashmap so they may be garbage collected. + */ +class ContextImageCache implements ImageCache { + + // if this cache is collective then images can be shared + // among contexts, this implies that the base directory + // is either the same or does not effect the images being + // loaded + private boolean collective; + private Map contextStore = Collections.synchronizedMap(new java.util.HashMap()); + private Set invalid = null; + private Map weakStore = null; + + public ContextImageCache(boolean col) { + collective = col; + if (collective) { + weakStore = Collections.synchronizedMap(new java.util.WeakHashMap()); + invalid = Collections.synchronizedSet(new java.util.HashSet()); + } + } + + // sync around lookups and puts + // another sync around load for a particular image + public FopImage getImage(String url, FOUserAgent context) { + ImageLoader im = null; + // this protects the finding or creating of a new + // ImageLoader for multi threads + synchronized (this) { + if (collective && invalid.contains(url)) { + return null; + } + Context con = (Context) contextStore.get(context); + if (con == null) { + con = new Context(context, collective); + contextStore.put(context, con); + } else { + if (con.invalid(url)) { + return null; + } + im = con.getImage(url); + } + if (im == null && collective) { + Iterator i = contextStore.values().iterator(); + while (i.hasNext()) { + Context c = (Context)i.next(); + if (c != con) { + im = c.getImage(url); + if (im != null) { + break; + } + } + } + if (im == null) { + im = (ImageLoader) weakStore.get(url); + } + } + + if (im != null) { + con.putImage(url, im); + } else { + im = con.getImage(url, this); + } + } + + // the ImageLoader is synchronized so images with the + // same url will not be loaded at the same time + if (im != null) { + return im.loadImage(); + } + return null; + } + + public void releaseImage(String url, FOUserAgent context) { + Context con = (Context) contextStore.get(context); + if (con != null) { + if (collective) { + ImageLoader im = con.getImage(url); + weakStore.put(url, im); + } + con.releaseImage(url); + } + } + + public void invalidateImage(String url, FOUserAgent context) { + if (collective) { + // cap size of invalid list + if (invalid.size() > 100) { + invalid.clear(); + } + invalid.add(url); + } + Context con = (Context) contextStore.get(context); + if (con != null) { + con.invalidateImage(url); + } + } + + public void removeContext(FOUserAgent context) { + Context con = (Context) contextStore.get(context); + if (con != null) { + if (collective) { + Map images = con.getImages(); + weakStore.putAll(images); + } + contextStore.remove(context); + } + } + + class Context { + private Map images = Collections.synchronizedMap(new java.util.HashMap()); + private Set invalid = null; + private FOUserAgent userAgent; + + public Context(FOUserAgent ua, boolean inv) { + userAgent = ua; + if (inv) { + invalid = Collections.synchronizedSet(new java.util.HashSet()); + } + } + + public ImageLoader getImage(String url, ImageCache c) { + if (images.containsKey(url)) { + return (ImageLoader) images.get(url); + } + ImageLoader loader = new ImageLoader(url, c, userAgent); + images.put(url, loader); + return loader; + } + + public void putImage(String url, ImageLoader image) { + images.put(url, image); + } + + public ImageLoader getImage(String url) { + return (ImageLoader) images.get(url); + } + + public void releaseImage(String url) { + images.remove(url); + } + + public Map getImages() { + return images; + } + + public void invalidateImage(String url) { + invalid.add(url); + } + + public boolean invalid(String url) { + return invalid.contains(url); + } + + } + +} + diff --git a/src/java/org/apache/fop/image/ImageLoader.java b/src/java/org/apache/fop/image/ImageLoader.java new file mode 100644 index 000000000..9d4a667f3 --- /dev/null +++ b/src/java/org/apache/fop/image/ImageLoader.java @@ -0,0 +1,94 @@ +/* + * $Id: ImageLoader.java,v 1.6 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +import org.apache.fop.fo.FOUserAgent; + +/** + * Class to load images. + */ +class ImageLoader { + + private String url; + private ImageCache cache; + private boolean valid = true; + private FOUserAgent userAgent; + private FopImage image = null; + + /** + * Main constructor. + * @param url URL to the image + * @param cache Image cache + * @param ua User agent + */ + public ImageLoader(String url, ImageCache cache, FOUserAgent ua) { + this.url = url; + this.cache = cache; + this.userAgent = ua; + } + + /** + * Loads the image. + * @return the loaded image + */ + public synchronized FopImage loadImage() { + if (!valid || image != null) { + return image; + } + image = ImageFactory.loadImage(url, userAgent); + if (image == null) { + cache.invalidateImage(url, userAgent); + valid = false; + } + return image; + } + +} diff --git a/src/java/org/apache/fop/image/JAIImage.java b/src/java/org/apache/fop/image/JAIImage.java new file mode 100644 index 000000000..ced4ccb5b --- /dev/null +++ b/src/java/org/apache/fop/image/JAIImage.java @@ -0,0 +1,183 @@ +/* + * $Id: JAIImage.java,v 1.10 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// AWT +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.BufferedImage; +import java.awt.color.ColorSpace; + +// JAI +import javax.media.jai.JAI; +import javax.media.jai.RenderedOp; +// Sun codec +import com.sun.media.jai.codec.FileCacheSeekableStream; + +// FOP +import org.apache.fop.pdf.PDFColor; + +/** + * FopImage object using JAI. + * @author Eric SCHAEFFER + * @see AbstractFopImage + * @see FopImage + */ +public class JAIImage extends AbstractFopImage { + + public JAIImage(FopImage.ImageInfo imgReader) { + super(imgReader); + } + + protected void loadImage() { + try { + com.sun.media.jai.codec.FileCacheSeekableStream seekableInput = + new FileCacheSeekableStream(inputStream); + RenderedOp imageOp = JAI.create("stream", seekableInput); + inputStream.close(); + inputStream = null; + + this.height = imageOp.getHeight(); + this.width = imageOp.getWidth(); + + ColorModel cm = imageOp.getColorModel(); + this.bitsPerPixel = 8; + // this.bitsPerPixel = cm.getPixelSize(); + this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + + BufferedImage imageData = imageOp.getAsBufferedImage(); + int[] tmpMap = imageData.getRGB(0, 0, this.width, + this.height, null, 0, this.width); + + if (cm.hasAlpha()) { + // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); + + if (transparencyType == java.awt.Transparency.OPAQUE) { + this.isTransparent = false; + } else if (transparencyType == java.awt.Transparency.BITMASK) { + if (cm instanceof IndexColorModel) { + this.isTransparent = false; + byte[] alphas = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] reds = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] greens = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] blues = new byte[ + ((IndexColorModel) cm).getMapSize()]; + ((IndexColorModel) cm).getAlphas(alphas); + ((IndexColorModel) cm).getReds(reds); + ((IndexColorModel) cm).getGreens(greens); + ((IndexColorModel) cm).getBlues(blues); + for (int i = 0; + i < ((IndexColorModel) cm).getMapSize(); + i++) { + if ((alphas[i] & 0xFF) == 0) { + this.isTransparent = true; + this.transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); + break; + } + } + } else { + // TRANSLUCENT + /* + * this.isTransparent = false; + * for (int i = 0; i < this.width * this.height; i++) { + * if (cm.getAlpha(tmpMap[i]) == 0) { + * this.isTransparent = true; + * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]), + * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); + * break; + * } + * } + * // or use special API... + */ + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + + // Should take care of the ColorSpace and bitsPerPixel + this.bitmapsSize = this.width * this.height * 3; + this.bitmaps = new byte[this.bitmapsSize]; + for (int i = 0; i < this.height; i++) { + for (int j = 0; j < this.width; j++) { + int p = tmpMap[i * this.width + j]; + int r = (p >> 16) & 0xFF; + int g = (p >> 8) & 0xFF; + int b = (p) & 0xFF; + this.bitmaps[3 * (i * this.width + j)] = + (byte)(r & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 1] = + (byte)(g & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 2] = + (byte)(b & 0xFF); + } + } + + } catch (Exception ex) { + /*throw new FopImageException("Error while loading image " + + "" + " : " + + ex.getClass() + " - " + + ex.getMessage()); + */} + } + +} + diff --git a/src/java/org/apache/fop/image/JimiImage.java b/src/java/org/apache/fop/image/JimiImage.java new file mode 100644 index 000000000..de67345f2 --- /dev/null +++ b/src/java/org/apache/fop/image/JimiImage.java @@ -0,0 +1,216 @@ +/* + * $Id: JimiImage.java,v 1.18 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.awt.image.ImageProducer; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.color.ColorSpace; + +// Jimi +import com.sun.jimi.core.Jimi; + +// Avalon +import org.apache.avalon.framework.logger.Logger; + +// FOP +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.fo.FOUserAgent; + +/** + * FopImage object for several images types, using Jimi. + * See Jimi documentation for supported image types. + * @author Eric SCHAEFFER + * @see AbstractFopImage + * @see FopImage + */ +public class JimiImage extends AbstractFopImage { + + public JimiImage(FopImage.ImageInfo imgReader) { + super(imgReader); + try { + Class c = Class.forName("com.sun.jimi.core.Jimi"); + } catch (ClassNotFoundException e) { + //throw new FopImageException("Jimi image library not available"); + } + } + + protected boolean loadDimensions(FOUserAgent ua) { + if (this.bitmaps == null) { + loadImage(ua.getLogger()); + } + + return this.bitmaps != null; + } + + /** + * @see org.apache.fop.image.AbstractFopImage#loadBitmap(FOUserAgent) + */ + protected boolean loadBitmap(FOUserAgent ua) { + if (this.bitmaps == null) { + loadImage(ua.getLogger()); + } + + return this.bitmaps != null; + } + + protected void loadImage(Logger log) { + int[] tmpMap = null; + try { + ImageProducer ip = + Jimi.getImageProducer(inputStream, + Jimi.SYNCHRONOUS | Jimi.IN_MEMORY); + FopImageConsumer consumer = new FopImageConsumer(ip); + ip.startProduction(consumer); + + while (!consumer.isImageReady()) { + Thread.sleep(500); + } + this.height = consumer.getHeight(); + this.width = consumer.getWidth(); + + inputStream.close(); + inputStream = null; + + try { + tmpMap = consumer.getImage(); + } catch (Exception ex) { + log.error("Image grabbing interrupted", ex); + return; + } + + ColorModel cm = consumer.getColorModel(); + this.bitsPerPixel = 8; + // this.bitsPerPixel = cm.getPixelSize(); + this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + if (cm.hasAlpha()) { + // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT + int transparencyType = cm.getTransparency(); + if (transparencyType == java.awt.Transparency.OPAQUE) { + this.isTransparent = false; + } else if (transparencyType == java.awt.Transparency.BITMASK) { + if (cm instanceof IndexColorModel) { + this.isTransparent = false; + byte[] alphas = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] reds = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] greens = new byte[ + ((IndexColorModel) cm).getMapSize()]; + byte[] blues = new byte[ + ((IndexColorModel) cm).getMapSize()]; + ((IndexColorModel) cm).getAlphas(alphas); + ((IndexColorModel) cm).getReds(reds); + ((IndexColorModel) cm).getGreens(greens); + ((IndexColorModel) cm).getBlues(blues); + for (int i = 0; + i < ((IndexColorModel) cm).getMapSize(); + i++) { + if ((alphas[i] & 0xFF) == 0) { + this.isTransparent = true; + this.transparentColor = new PDFColor( + (int)(reds[i] & 0xFF), + (int)(greens[i] & 0xFF), + (int)(blues[i] & 0xFF)); + break; + } + } + } else { + // TRANSLUCENT + /* + * this.isTransparent = false; + * for (int i = 0; i < this.width * this.height; i++) { + * if (cm.getAlpha(tmpMap[i]) == 0) { + * this.isTransparent = true; + * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]), + * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); + * break; + * } + * } + */ + // use special API... + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + } else { + this.isTransparent = false; + } + } catch (Throwable ex) { + log.error("Error while loading image " + + "", ex); + return; + } + + + // Should take care of the ColorSpace and bitsPerPixel + this.bitmapsSize = this.width * this.height * 3; + this.bitmaps = new byte[this.bitmapsSize]; + for (int i = 0; i < this.height; i++) { + for (int j = 0; j < this.width; j++) { + int p = tmpMap[i * this.width + j]; + int r = (p >> 16) & 0xFF; + int g = (p >> 8) & 0xFF; + int b = (p) & 0xFF; + this.bitmaps[3 * (i * this.width + j)] = + (byte)(r & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 1] = + (byte)(g & 0xFF); + this.bitmaps[3 * (i * this.width + j) + 2] = + (byte)(b & 0xFF); + } + } + } + +} + diff --git a/src/java/org/apache/fop/image/JpegImage.java b/src/java/org/apache/fop/image/JpegImage.java new file mode 100644 index 000000000..2cf9a125f --- /dev/null +++ b/src/java/org/apache/fop/image/JpegImage.java @@ -0,0 +1,235 @@ +/* + * $Id: JpegImage.java,v 1.12 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import java.io.ByteArrayOutputStream; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; + +// FOP +import org.apache.fop.fo.FOUserAgent; + +/** + * FopImage object for JPEG images, Using Java native classes. + * @author Eric Dalquist + * @see AbstractFopImage + * @see FopImage + */ +public class JpegImage extends AbstractFopImage { + private ICC_Profile iccProfile = null; + private boolean foundICCProfile = false; + private boolean foundDimensions = false; + + /** + * Create a jpeg image with the info. + * + * @param imgInfo the image info for this jpeg + */ + public JpegImage(FopImage.ImageInfo imgInfo) { + super(imgInfo); + } + + /** + * Load the original jpeg data. + * This loads the original jpeg data and reads the color space, + * and icc profile if any. + * + * @param ua the user agent + * @return true if loaded false for any error + */ + protected boolean loadOriginalData(FOUserAgent ua) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream iccStream = new ByteArrayOutputStream(); + int index = 0; + boolean cont = true; + + try { + byte[] readBuf = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(readBuf)) != -1) { + baos.write(readBuf, 0, bytesRead); + } + inputStream.close(); + inputStream = null; + } catch (java.io.IOException ex) { + ua.getLogger().error("Error while loading image " + + " : " + ex.getClass() + + " - " + ex.getMessage(), ex); + return false; + } + + this.bitmaps = baos.toByteArray(); + this.bitsPerPixel = 8; + this.isTransparent = false; + + if (this.bitmaps.length > (index + 2) + && uByte(this.bitmaps[index]) == 255 + && uByte(this.bitmaps[index + 1]) == 216) { + index += 2; + + while (index < this.bitmaps.length && cont) { + //check to be sure this is the begining of a header + if (this.bitmaps.length > (index + 2) + && uByte(this.bitmaps[index]) == 255) { + + //192 or 194 are the header bytes that contain + // the jpeg width height and color depth. + if (uByte(this.bitmaps[index + 1]) == 192 + || uByte(this.bitmaps[index + 1]) == 194) { + + this.height = calcBytes(this.bitmaps[index + 5], + this.bitmaps[index + 6]); + this.width = calcBytes(this.bitmaps[index + 7], + this.bitmaps[index + 8]); + + if (this.bitmaps[index + 9] == 1) { + this.colorSpace = ColorSpace.getInstance( + ColorSpace.CS_GRAY); + } else if (this.bitmaps[index + 9] == 3) { + this.colorSpace = ColorSpace.getInstance( + ColorSpace.CS_LINEAR_RGB); + } else if (this.bitmaps[index + 9] == 4) { + // howto create CMYK color space + this.colorSpace = ColorSpace.getInstance( + ColorSpace.CS_CIEXYZ); + } else { + ua.getLogger().error("Unknown ColorSpace for image: " + + ""); + return false; + } + + foundDimensions = true; + if (foundICCProfile) { + cont = false; + break; + } + index += calcBytes(this.bitmaps[index + 2], + this.bitmaps[index + 3]) + 2; + + } else if (uByte(this.bitmaps[index + 1]) == 226 + && this.bitmaps.length > (index + 60)) { + // Check if ICC profile + byte[] iccString = new byte[11]; + System.arraycopy(this.bitmaps, index + 4, + iccString, 0, 11); + + if ("ICC_PROFILE".equals(new String(iccString))) { + int chunkSize = calcBytes( + this.bitmaps[index + 2], + this.bitmaps[index + 3]) + 2; + + iccStream.write(this.bitmaps, + index + 18, chunkSize - 18); + + } + + index += calcBytes(this.bitmaps[index + 2], + this.bitmaps[index + 3]) + 2; + } else { + index += calcBytes(this.bitmaps[index + 2], + this.bitmaps[index + 3]) + 2; + } + + } else { + cont = false; + } + } + } else { + ua.getLogger().error("Error while loading " + + "JpegImage - Invalid JPEG Header."); + return false; + } + if (iccStream.size() > 0) { + byte[] align = new byte[((iccStream.size()) % 8) + 8]; + try { + iccStream.write(align); + } catch (Exception e) { + ua.getLogger().error("Error while loading image " + + " : " + + e.getMessage(), e); + return false; + } + try { + iccProfile = ICC_Profile.getInstance(iccStream.toByteArray()); + } catch (Exception e) { + ua.getLogger().error("Invalid ICC profile: " + e, e); + return false; + } + } else if (this.colorSpace == null) { + ua.getLogger().error("ColorSpace not specified for JPEG image"); + return false; + } + return true; + } + + /** + * Get the ICC profile for this Jpeg image. + * + * @return the icc profile or null if not found + */ + public ICC_Profile getICCProfile() { + return iccProfile; + } + + private int calcBytes(byte bOne, byte bTwo) { + return (uByte(bOne) * 256) + uByte(bTwo); + } + + private int uByte(byte bIn) { + if (bIn < 0) { + return 256 + bIn; + } else { + return bIn; + } + } +} + diff --git a/src/java/org/apache/fop/image/XMLImage.java b/src/java/org/apache/fop/image/XMLImage.java new file mode 100644 index 000000000..8f655bb23 --- /dev/null +++ b/src/java/org/apache/fop/image/XMLImage.java @@ -0,0 +1,108 @@ +/* + * $Id: XMLImage.java,v 1.4 2003/03/06 21:25:44 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image; + +// Java +import org.w3c.dom.Document; + +// FOP +import org.apache.fop.apps.Driver; + +/** + * This is an implementation for XML-based images such as SVG. + * + * @see AbstractFopImage + * @see FopImage + */ +public class XMLImage extends AbstractFopImage { + + private Document doc; + private String namespace = ""; + + /** + * @see org.apache.fop.image.AbstractFopImage#AbstractFopImage(ImageInfo) + */ + public XMLImage(FopImage.ImageInfo imgInfo) { + super(imgInfo); + if (imgInfo.data instanceof Document) { + doc = (Document)imgInfo.data; + loaded = loaded | ORIGINAL_DATA; + } + namespace = imgInfo.str; + } + + /** + * creates a SAX parser, using the value of org.xml.sax.parser + * defaulting to org.apache.xerces.parsers.SAXParser + * + * @return the created SAX parser + */ + public static String getParserName() { + String parserClassName = Driver.getParserClassName(); + return parserClassName; + } + + /** + * Returns the XML document as a DOM document. + * @return the DOM document + */ + public Document getDocument() { + return this.doc; + } + + /** + * Returns the namespace of the XML document. + * @return the namespace + */ + public String getNameSpace() { + return this.namespace; + } +} diff --git a/src/java/org/apache/fop/image/analyser/BMPReader.java b/src/java/org/apache/fop/image/analyser/BMPReader.java new file mode 100644 index 000000000..c97d0778b --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/BMPReader.java @@ -0,0 +1,136 @@ +/* + * $Id: BMPReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for BMP image type. + * + * @author Pankaj Narula + * @version $Id: BMPReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + */ +public class BMPReader implements ImageReader { + + /** Length of the BMP header */ + protected static final int BMP_SIG_LENGTH = 26; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) throws IOException { + byte[] header = getDefaultHeader(bis); + boolean supported = ((header[0] == (byte) 0x42) + && (header[1] == (byte) 0x4d)); + if (supported) { + FopImage.ImageInfo info = getDimension(header); + info.inputStream = bis; + return info; + } else { + return null; + } + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/bmp"; + } + + private FopImage.ImageInfo getDimension(byte[] header) { + FopImage.ImageInfo info = new FopImage.ImageInfo(); + info.mimeType = getMimeType(); + + // little endian notation + int byte1 = header[18] & 0xff; + int byte2 = header[19] & 0xff; + int byte3 = header[20] & 0xff; + int byte4 = header[21] & 0xff; + long l = (long) ((byte4 << 24) | (byte3 << 16) + | (byte2 << 8) | byte1); + info.width = (int) (l & 0xffffffff); + + byte1 = header[22] & 0xff; + byte2 = header[23] & 0xff; + byte3 = header[24] & 0xff; + byte4 = header[25] & 0xff; + l = (long) ((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); + info.height = (int) (l & 0xffffffff); + return info; + } + + private byte[] getDefaultHeader(InputStream imageStream) + throws IOException { + byte[] header = new byte[BMP_SIG_LENGTH]; + try { + imageStream.mark(BMP_SIG_LENGTH + 1); + imageStream.read(header); + imageStream.reset(); + } catch (IOException ex) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ex; + } + return header; + } + +} diff --git a/src/java/org/apache/fop/image/analyser/EPSReader.java b/src/java/org/apache/fop/image/analyser/EPSReader.java new file mode 100644 index 000000000..1ea9833be --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/EPSReader.java @@ -0,0 +1,280 @@ +/* + * $Id: EPSReader.java,v 1.9 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.image.EPSImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for EPS document image type. + * + * @version $Id: EPSReader.java,v 1.9 2003/03/06 21:25:45 jeremias Exp $ + */ +public class EPSReader implements ImageReader { + + private static final byte[] EPS_HEADER_ASCII = "%!PS".getBytes(); + private static final byte[] BOUNDINGBOX = "%%BoundingBox: ".getBytes(); + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) throws IOException { + + boolean isEPS = false; + + bis.mark(32); + byte[] header = new byte[30]; + bis.read(header, 0, 30); + bis.reset(); + + EPSImage.EPSData data = new EPSImage.EPSData(); + + // Check if binary header + if (getLong(header, 0) == 0xC6D3D0C5) { + data.isAscii = false; + isEPS = true; + + data.psStart = getLong(header, 4); + data.psLength = getLong(header, 8); + data.wmfStart = getLong(header, 12); + data.wmfLength = getLong(header, 16); + data.tiffStart = getLong(header, 20); + data.tiffLength = getLong(header, 24); + + } else { + // Check if plain ascii + byte[] epsh = "%!PS".getBytes(); + if (EPS_HEADER_ASCII[0] == header[0] + && EPS_HEADER_ASCII[1] == header[1] + && EPS_HEADER_ASCII[2] == header[2] + && EPS_HEADER_ASCII[3] == header[3]) { + data.isAscii = true; + isEPS = true; + } + } + + if (isEPS) { + FopImage.ImageInfo info = new FopImage.ImageInfo(); + info.mimeType = getMimeType(); + info.data = data; + readEPSImage(bis, data); + data.bbox = readBBox(data); + + if (data.bbox != null) { + info.width = (int) (data.bbox[2] - data.bbox[0]); + info.height = (int) (data.bbox[3] - data.bbox[1]); + + // image data read + bis.close(); + info.inputStream = null; + + return info; + } else { + // Ain't eps if no BoundingBox + isEPS = false; + } + } + + return null; + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/eps"; + } + + private long getLong(byte[] buf, int idx) { + int b1 = buf[idx] & 0xff; + int b2 = buf[idx + 1] & 0xff; + int b3 = buf[idx + 2] & 0xff; + int b4 = buf[idx + 3] & 0xff; + + return (long) ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); + } + + /** + * Read the eps file and extract eps part. + * + * @param bis The InputStream + * @param data EPSData object to write the results to + * @exception IOException If an I/O error occurs + */ + private void readEPSImage(InputStream bis, EPSImage.EPSData data) + throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] file; + byte[] readBuf = new byte[20480]; + int bytesRead; + int index = 0; + boolean cont = true; + + try { + while ((bytesRead = bis.read(readBuf)) != -1) { + baos.write(readBuf, 0, bytesRead); + } + } catch (java.io.IOException ex) { + throw new IOException("Error while loading EPS image: " + + ex.getMessage()); + } + + file = baos.toByteArray(); + + if (data.isAscii) { + data.rawEps = null; + data.epsFile = new byte[file.length]; + System.arraycopy(file, 0, data.epsFile, 0, data.epsFile.length); + } else { + data.rawEps = new byte[file.length]; + data.epsFile = new byte[(int) data.psLength]; + System.arraycopy(file, 0, data.rawEps, 0, data.rawEps.length); + System.arraycopy(data.rawEps, (int) data.psStart, data.epsFile, 0, + (int) data.psLength); + } + } + + /** + * Get embedded TIFF preview or null. + * + * @param data The EPS payload + * @return The embedded preview + */ + public byte[] getPreview(EPSImage.EPSData data) { + if (data.preview == null) { + if (data.tiffLength > 0) { + data.preview = new byte[(int) data.tiffLength]; + System.arraycopy(data.rawEps, (int) data.tiffStart, data.preview, 0, + (int) data.tiffLength); + } + } + return data.preview; + } + + /** + * Extract bounding box from eps part. + * + * @param data The EPS payload + * @return An Array of four coordinates making up the bounding box + */ + private long[] readBBox(EPSImage.EPSData data) { + long[] mbbox = null; + int idx = 0; + boolean found = false; + + while (!found && (data.epsFile.length > (idx + BOUNDINGBOX.length))) { + boolean sfound = true; + int i = idx; + for (i = idx; sfound && (i - idx) < BOUNDINGBOX.length; i++) { + if (BOUNDINGBOX[i - idx] != data.epsFile[i]) { + sfound = false; + } + } + if (sfound) { + found = true; + idx = i; + } else { + idx++; + } + } + + if (!found) { + return mbbox; + } + + mbbox = new long[4]; + idx += readLongString(data, mbbox, 0, idx); + idx += readLongString(data, mbbox, 1, idx); + idx += readLongString(data, mbbox, 2, idx); + idx += readLongString(data, mbbox, 3, idx); + + return mbbox; + } + + private int readLongString(EPSImage.EPSData data, long[] mbbox, int i, int idx) { + while (idx < data.epsFile.length && (data.epsFile[idx] == 32)) { + idx++; + } + + int nidx = idx; + + // check also for ANSI46(".") to identify floating point values + while (nidx < data.epsFile.length + && ((data.epsFile[nidx] >= 48 && data.epsFile[nidx] <= 57) + || (data.epsFile[nidx] == 45) + || (data.epsFile[nidx] == 46))) { + nidx++; + } + + byte[] num = new byte[nidx - idx]; + System.arraycopy(data.epsFile, idx, num, 0, nidx - idx); + String ns = new String(num); + + //if( ns.indexOf(".") != -1 ) { + // do something like logging a warning + //} + + // then parse the double and round off to the next math. Integer + mbbox[i] = (long) Math.ceil(Double.parseDouble(ns)); + + return (1 + nidx - idx); + } + +} + diff --git a/src/java/org/apache/fop/image/analyser/GIFReader.java b/src/java/org/apache/fop/image/analyser/GIFReader.java new file mode 100644 index 000000000..311320ee3 --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/GIFReader.java @@ -0,0 +1,132 @@ +/* + * $Id: GIFReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for GIF image type. + * + * @author Pankaj Narula + * @version $Id: GIFReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + */ +public class GIFReader implements ImageReader { + + private static final int GIF_SIG_LENGTH = 10; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) throws IOException { + byte[] header = getDefaultHeader(bis); + boolean supported = ((header[0] == 'G') + && (header[1] == 'I') + && (header[2] == 'F') + && (header[3] == '8') + && (header[4] == '7' || header[4] == '9') + && (header[5] == 'a')); + if (supported) { + FopImage.ImageInfo info = getDimension(header); + info.mimeType = getMimeType(); + info.inputStream = bis; + return info; + } else { + return null; + } + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/gif"; + } + + private FopImage.ImageInfo getDimension(byte[] header) { + FopImage.ImageInfo info = new FopImage.ImageInfo(); + // little endian notation + int byte1 = header[6] & 0xff; + int byte2 = header[7] & 0xff; + info.width = ((byte2 << 8) | byte1) & 0xffff; + + byte1 = header[8] & 0xff; + byte2 = header[9] & 0xff; + info.height = ((byte2 << 8) | byte1) & 0xffff; + return info; + } + + private byte[] getDefaultHeader(InputStream imageStream) + throws IOException { + byte[] header = new byte[GIF_SIG_LENGTH]; + try { + imageStream.mark(GIF_SIG_LENGTH + 1); + imageStream.read(header); + imageStream.reset(); + } catch (IOException ex) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ex; + } + return header; + } + +} + diff --git a/src/java/org/apache/fop/image/analyser/ImageReader.java b/src/java/org/apache/fop/image/analyser/ImageReader.java new file mode 100644 index 000000000..f9b959745 --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/ImageReader.java @@ -0,0 +1,87 @@ +/* + * $Id: ImageReader.java,v 1.9 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader objects read image headers to determine the image size. + * + * @author Pankaj Narula + * @version $Id: ImageReader.java,v 1.9 2003/03/06 21:25:45 jeremias Exp $ + */ +public interface ImageReader { + + /** + * Verify image type. If the stream does not contain image data expected by + * the reader it must reset the stream to the start. This is so that the + * next reader can start reading from the start. The reader must not close + * the stream unless it can handle the image and it has read the + * information. + * + * @param bis Image buffered input stream + * @param uri URI to the image + * @param ua The user agent + * @return true if image type is the handled one + * @exception IOException if an I/O error occurs + */ + FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) + throws IOException; + +} + diff --git a/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java b/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java new file mode 100644 index 000000000..5d88fe958 --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java @@ -0,0 +1,123 @@ +/* + * $Id: ImageReaderFactory.java,v 1.13 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; +import java.util.ArrayList; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * Factory for ImageReader objects. + * + * @author Pankaj Narula + * @version $Id: ImageReaderFactory.java,v 1.13 2003/03/06 21:25:45 jeremias Exp $ + */ +public class ImageReaderFactory { + + private static ArrayList formats = new ArrayList(); + + static { + registerFormat(new JPEGReader()); + registerFormat(new BMPReader()); + registerFormat(new GIFReader()); + registerFormat(new PNGReader()); + registerFormat(new TIFFReader()); + registerFormat(new EPSReader()); + // the xml parser through batik closes the stream when finished + // so there is a workaround in the SVGReader + registerFormat(new SVGReader()); + registerFormat(new XMLReader()); + } + + /** + * Registers a new ImageReader. + * + * @param reader An ImageReader instance + */ + public static void registerFormat(ImageReader reader) { + formats.add(reader); + } + + /** + * ImageReader maker. + * + * @param uri URI to the image + * @param in image input stream + * @param ua user agent + * @return An ImageInfo object describing the image + */ + public static FopImage.ImageInfo make(String uri, InputStream in, + FOUserAgent ua) { + + ImageReader reader; + try { + for (int count = 0; count < formats.size(); count++) { + reader = (ImageReader) formats.get(count); + FopImage.ImageInfo info = reader.verifySignature(uri, in, ua); + if (info != null) { + return info; + } + } + } catch (IOException ex) { + ua.getLogger().error( + "Error while recovering Image Informations (" + + uri + ")", ex); + } + return null; + } + +} + diff --git a/src/java/org/apache/fop/image/analyser/JPEGReader.java b/src/java/org/apache/fop/image/analyser/JPEGReader.java new file mode 100644 index 000000000..32597d7cc --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/JPEGReader.java @@ -0,0 +1,195 @@ +/* + * $Id: JPEGReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for JPEG image type. + * + * @author Pankaj Narula + * @version $Id: JPEGReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + */ +public class JPEGReader implements ImageReader { + + /** + * Only SOFn and APPn markers are defined as SOFn is needed for the height and + * width search. APPn is also defined because if the JPEG contains thumbnails + * the dimensions of the thumnail would also be after the SOFn marker enclosed + * inside the APPn marker. And we don't want to confuse those dimensions with + * the image dimensions. + */ + private static final int MARK = 0xff; // Beginning of a Marker + private static final int NULL = 0x00; // Special case for 0xff00 + private static final int SOF1 = 0xc0; // Baseline DCT + private static final int SOF2 = 0xc1; // Extended Sequential DCT + private static final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 + private static final int SOFA = 0xca; // Progressice DCT only PDF 1.3 + private static final int APP0 = 0xe0; // Application marker, JFIF + private static final int APPF = 0xef; // Application marker + private static final int SOS = 0xda; // Start of Scan + private static final int SOI = 0xd8; // start of Image + private static final int JPG_SIG_LENGTH = 2; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream fis, + FOUserAgent ua) throws IOException { + byte[] header = getDefaultHeader(fis); + boolean supported = ((header[0] == (byte) 0xff) + && (header[1] == (byte) 0xd8)); + if (supported) { + FopImage.ImageInfo info = getDimension(fis); + info.mimeType = getMimeType(); + info.inputStream = fis; + return info; + } else { + return null; + } + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/jpeg"; + } + + private byte[] getDefaultHeader(InputStream imageStream) throws IOException { + byte[] header = new byte[JPG_SIG_LENGTH]; + try { + imageStream.mark(JPG_SIG_LENGTH + 1); + imageStream.read(header); + imageStream.reset(); + } catch (IOException ex) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ex; + } + return header; + } + + private FopImage.ImageInfo getDimension(InputStream imageStream) throws IOException { + FopImage.ImageInfo info = new FopImage.ImageInfo(); + try { + imageStream.mark(imageStream.available()); + int marker = NULL; + long length, skipped; +outer: + while (imageStream.available() > 0) { + while ((marker = imageStream.read()) != MARK) { + //nop, simply skip + } + + do { + marker = imageStream.read(); + } while (marker == MARK); + + switch (marker) { + case SOI: + break; + case NULL: + break; + case SOF1: + case SOF2: + case SOF3: // SOF3 and SOFA are only supported by PDF 1.3 + case SOFA: + this.skip(imageStream, 3); + info.height = this.read2bytes(imageStream); + info.width = this.read2bytes(imageStream); + break outer; + default: + length = this.read2bytes(imageStream); + skipped = this.skip(imageStream, length - 2); + if (skipped != length - 2) { + throw new IOException("Skipping Error"); + } + } + } + imageStream.reset(); + } catch (IOException ioe) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ioe; + } + return info; + } + + private int read2bytes(InputStream imageStream) throws IOException { + int byte1 = imageStream.read(); + int byte2 = imageStream.read(); + return (int) ((byte1 << 8) | byte2); + } + + private long skip(InputStream imageStream, long n) throws IOException { + long discarded = 0; + while (discarded != n) { + imageStream.read(); + discarded++; + } + return discarded; // scope for exception + } + +} + diff --git a/src/java/org/apache/fop/image/analyser/PNGReader.java b/src/java/org/apache/fop/image/analyser/PNGReader.java new file mode 100644 index 000000000..58748988f --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/PNGReader.java @@ -0,0 +1,144 @@ +/* + * $Id: PNGReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for PNG image type. + * + * @author Pankaj Narula + * @version $Id: PNGReader.java,v 1.8 2003/03/06 21:25:45 jeremias Exp $ + */ +public class PNGReader implements ImageReader { + + private static final int PNG_SIG_LENGTH = 24; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) throws IOException { + byte[] header = getDefaultHeader(bis); + boolean supported = ((header[0] == (byte) 0x89) + && (header[1] == (byte) 0x50) + && (header[2] == (byte) 0x4e) + && (header[3] == (byte) 0x47) + && (header[4] == (byte) 0x0d) + && (header[5] == (byte) 0x0a) + && (header[6] == (byte) 0x1a) + && (header[7] == (byte) 0x0a)); + + if (supported) { + FopImage.ImageInfo info = getDimension(header); + info.mimeType = getMimeType(); + info.inputStream = bis; + return info; + } else { + return null; + } + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/png"; + } + + private FopImage.ImageInfo getDimension(byte[] header) { + FopImage.ImageInfo info = new FopImage.ImageInfo(); + + // png is always big endian + int byte1 = header[16] & 0xff; + int byte2 = header[17] & 0xff; + int byte3 = header[18] & 0xff; + int byte4 = header[19] & 0xff; + long l = (long) ((byte1 << 24) + | (byte2 << 16) + | (byte3 << 8) + | (byte4)); + info.width = (int) l; + + byte1 = header[20] & 0xff; + byte2 = header[21] & 0xff; + byte3 = header[22] & 0xff; + byte4 = header[23] & 0xff; + l = (long) ((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); + info.height = (int) l; + return info; + } + + private byte[] getDefaultHeader(InputStream imageStream) + throws IOException { + byte[] header = new byte[PNG_SIG_LENGTH]; + try { + imageStream.mark(PNG_SIG_LENGTH + 1); + imageStream.read(header); + imageStream.reset(); + } catch (IOException ex) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ex; + } + return header; + } + +} diff --git a/src/java/org/apache/fop/image/analyser/SVGReader.java b/src/java/org/apache/fop/image/analyser/SVGReader.java new file mode 100644 index 000000000..c8e9145e9 --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/SVGReader.java @@ -0,0 +1,261 @@ +/* + * $Id: SVGReader.java,v 1.27 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; +import java.awt.geom.AffineTransform; + +// XML +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGDocument; + +// Batik +import org.apache.batik.dom.svg.SAXSVGDocumentFactory; +import org.apache.batik.dom.svg.SVGOMDocument; +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.UnitProcessor; +import org.apache.batik.dom.svg.SVGDOMImplementation; + +// FOP +import org.apache.fop.image.XMLImage; +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.svg.SVGUserAgent; + +/** + * ImageReader object for SVG document image type. + */ +public class SVGReader implements ImageReader { + + /** SVG's MIME type */ + public static final String SVG_MIME_TYPE = "image/svg+xml"; + + private boolean batik = true; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream fis, + FOUserAgent ua) throws IOException { + FopImage.ImageInfo info = loadImage(uri, fis, ua); + if (info != null) { + try { + fis.close(); + } catch (Exception e) { + //ignore + } + } + return info; + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return SVG_MIME_TYPE; + } + + /** + * This means the external svg document will be loaded twice. Possibly need + * a slightly different design for the image stuff. + * + * @param uri @todo Description of the Parameter + * @param fis @todo Description of the Parameter + * @param ua @todo Description of the Parameter + * @return @todo Description of the Return Value + */ + private FopImage.ImageInfo loadImage(String uri, InputStream bis, + FOUserAgent ua) { + if (batik) { + try { + Loader loader = new Loader(); + return loader.getImage(uri, bis, ua); + } catch (NoClassDefFoundError e) { + batik = false; + //ua.getLogger().error("Batik not in class path", e); + return null; + } + } + return null; + } + + /** + * This method is put in another class so that the classloader does not + * attempt to load batik related classes when constructing the SVGReader + * class. + */ + class Loader { + private FopImage.ImageInfo getImage(String uri, InputStream fis, + FOUserAgent ua) { + // parse document and get the size attributes of the svg element + + try { + int length = 5; + fis.mark(length); + byte[] b = new byte[length]; + fis.read(b); + String start = new String(b); + fis.reset(); + + if (start.equals(". For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** + * ImageReader object for TIFF image type. + * + * @author Pankaj Narula, Michael Lee + * @version $Id: TIFFReader.java,v 1.9 2003/03/06 21:25:45 jeremias Exp $ + */ +public class TIFFReader implements ImageReader { + + private static final int TIFF_SIG_LENGTH = 8; + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream bis, + FOUserAgent ua) throws IOException { + byte[] header = getDefaultHeader(bis); + boolean supported = false; + + // first 2 bytes = II (little endian encoding) + if (header[0] == (byte) 0x49 && header[1] == (byte) 0x49) { + + // look for '42' in byte 3 and '0' in byte 4 + if (header[2] == 42 && header[3] == 0) { + supported = true; + } + } + + // first 2 bytes == MM (big endian encoding) + if (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D) { + + // look for '42' in byte 4 and '0' in byte 3 + if (header[2] == 0 && header[3] == 42) { + supported = true; + } + } + + if (supported) { + FopImage.ImageInfo info = getDimension(header); + info.mimeType = getMimeType(); + info.inputStream = bis; + return info; + } else { + return null; + } + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "image/tiff"; + } + + private FopImage.ImageInfo getDimension(byte[] header) { + // currently not setting the width and height + // these are set again by the Jimi image reader. + // I suppose I'll do it one day to be complete. Or + // someone else will. + // Note: bytes 4,5,6,7 contain the byte offset in the stream of the first IFD block + /* + * //png is always big endian + * int byte1 = header[ 16 ] & 0xff; + * int byte2 = header[ 17 ] & 0xff; + * int byte3 = header[ 18 ] & 0xff; + * int byte4 = header[ 19 ] & 0xff; + * long l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) | + * ( byte3 << 8 ) | byte4 ); + * this.width = ( int ) ( l ); + * byte1 = header[ 20 ] & 0xff; + * byte2 = header[ 21 ] & 0xff; + * byte3 = header[ 22 ] & 0xff; + * byte4 = header[ 23 ] & 0xff; + * l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) | ( byte3 << 8 ) | + * byte4 ); + * this.height = ( int ) ( l ); + */ + FopImage.ImageInfo info = new FopImage.ImageInfo(); + info.width = -1; + info.height = -1; + return info; + } + + private byte[] getDefaultHeader(InputStream imageStream) + throws IOException { + byte[] header = new byte[TIFF_SIG_LENGTH]; + try { + imageStream.mark(TIFF_SIG_LENGTH + 1); + imageStream.read(header); + imageStream.reset(); + } catch (IOException ex) { + try { + imageStream.reset(); + } catch (IOException exbis) { + // throw the original exception, not this one + } + throw ex; + } + return header; + } + +} + diff --git a/src/java/org/apache/fop/image/analyser/XMLReader.java b/src/java/org/apache/fop/image/analyser/XMLReader.java new file mode 100644 index 000000000..5e5519517 --- /dev/null +++ b/src/java/org/apache/fop/image/analyser/XMLReader.java @@ -0,0 +1,182 @@ +/* + * $Id: XMLReader.java,v 1.6 2003/03/06 21:25:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.image.analyser; + +// Java +import java.io.InputStream; +import java.io.IOException; +import java.util.Map; + +// XML +import javax.xml.parsers.DocumentBuilderFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +// FOP +import org.apache.fop.image.FopImage; +import org.apache.fop.fo.FOUserAgent; + +/** ImageReader object for XML document image type. */ +public class XMLReader implements ImageReader { + + private static Map converters = new java.util.HashMap(); + + /** + * Registers a Converter implementation with XMLReader. + * + * @param ns The namespace to associate with this converter + * @param conv The actual Converter implementation + */ + public static void setConverter(String ns, Converter conv) { + converters.put(ns, conv); + } + + /** @see org.apache.fop.image.analyser.ImageReader */ + public FopImage.ImageInfo verifySignature(String uri, InputStream fis, + FOUserAgent ua) + throws IOException { + FopImage.ImageInfo info = loadImage(uri, fis, ua); + if (info != null) { + try { + fis.close(); + } catch (Exception e) { + //ignore + } + } + return info; + } + + /** + * Returns the MIME type supported by this implementation. + * + * @return The MIME type + */ + public String getMimeType() { + return "text/xml"; + } + + /** + * Creates an ImageInfo object from an XML image read from a stream. + * + * @todo This means the external svg document will be loaded twice. Possibly need + * a slightly different design for the image stuff. + * + * @param uri The URI to the image + * @param bis The InputStream + * @param ua The user agent + * @return An ImageInfo object describing the image + */ + protected FopImage.ImageInfo loadImage(String uri, InputStream bis, + FOUserAgent ua) { + return createDocument(bis, ua); + } + + /** + * Creates an ImageInfo object from an XML image read from a stream. + * + * @param is The InputStream + * @param ua The user agent + * @return An ImageInfo object describing the image + */ + public FopImage.ImageInfo createDocument(InputStream is, FOUserAgent ua) { + Document doc = null; + FopImage.ImageInfo info = new FopImage.ImageInfo(); + info.mimeType = getMimeType(); + + try { + int length = is.available(); + is.mark(length); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + doc = dbf.newDocumentBuilder().parse(is); + info.data = doc; + + Element root = doc.getDocumentElement(); + ua.getLogger().debug("XML image namespace: " + root.getAttribute("xmlns")); + String ns = root.getAttribute("xmlns"); + info.str = ns; + + Converter conv = (Converter) converters.get(ns); + if (conv != null) { + FopImage.ImageInfo i = conv.convert(doc); + if (i != null) { + info = i; + } + } + } catch (Exception e) { + ua.getLogger().warn("Error while constructing image from XML", e); + try { + is.reset(); + } catch (IOException ioe) { + // throw the original exception, not this one + } + return null; + } + return info; + } + + /** + * This interface is to be implemented for XML to image converters. + */ + public static interface Converter { + + /** + * This method is called for a DOM document to be converted into an + * ImageInfo object. + * + * @param doc The DOM document to convert + * @return An ImageInfo object describing the image + */ + FopImage.ImageInfo convert(Document doc); + } + +} + diff --git a/src/java/org/apache/fop/layout/AbsolutePositionProps.java b/src/java/org/apache/fop/layout/AbsolutePositionProps.java new file mode 100644 index 000000000..9e70580fb --- /dev/null +++ b/src/java/org/apache/fop/layout/AbsolutePositionProps.java @@ -0,0 +1,67 @@ +/* + * $Id: AbsolutePositionProps.java,v 1.4 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all hyphenation related properties on an FO. + * Public "structure" allows direct member access. + */ +public class AbsolutePositionProps { + public int absolutePosition; + public int top; + public int right; + public int bottom; + public int left; + + public AbsolutePositionProps() { + } + +} diff --git a/src/java/org/apache/fop/layout/AccessibilityProps.java b/src/java/org/apache/fop/layout/AccessibilityProps.java new file mode 100644 index 000000000..d13fe5d7f --- /dev/null +++ b/src/java/org/apache/fop/layout/AccessibilityProps.java @@ -0,0 +1,64 @@ +/* + * $Id: AccessibilityProps.java,v 1.2 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all hyphenation related properties on an FO. + * Public "structure" allows direct member access. + */ +public class AccessibilityProps { + public String sourceDoc = null; + public String role = null; + + public AccessibilityProps() { + } + +} diff --git a/src/java/org/apache/fop/layout/AreaClass.java b/src/java/org/apache/fop/layout/AreaClass.java new file mode 100644 index 000000000..50cdb490b --- /dev/null +++ b/src/java/org/apache/fop/layout/AreaClass.java @@ -0,0 +1,82 @@ +/* + * $Id: AreaClass.java,v 1.4 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +import org.apache.fop.apps.FOPException; + +/** + * This class defines area classes. + * @todo Would better be replaced by an Enum (Avalon or Commons) + */ +public class AreaClass { + public static final String UNASSIGNED = "unassigned"; + + public static final String XSL_NORMAL = "xsl-normal"; + public static final String XSL_ABSOLUTE = "xsl-absolute"; + public static final String XSL_FOOTNOTE = "xsl-footnote"; + public static final String XSL_SIDE_FLOAT = "xsl-side-float"; + public static final String XSL_BEFORE_FLOAT = "xsl-before-float"; + + // checker method + public static String setAreaClass(String areaClass) throws FOPException { + if (areaClass.equals(XSL_NORMAL) + || areaClass.equals(XSL_ABSOLUTE) + || areaClass.equals(XSL_FOOTNOTE) + || areaClass.equals(XSL_SIDE_FLOAT) + || areaClass.equals(XSL_BEFORE_FLOAT)) { + return areaClass; + } else { + throw new FOPException("Unknown area class '" + areaClass + "'"); + } + } + +} + diff --git a/src/java/org/apache/fop/layout/AuralProps.java b/src/java/org/apache/fop/layout/AuralProps.java new file mode 100644 index 000000000..65108fa5f --- /dev/null +++ b/src/java/org/apache/fop/layout/AuralProps.java @@ -0,0 +1,78 @@ +/* + * $Id: AuralProps.java,v 1.2 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all hyphenation related properties on an FO. + * Public "structure" allows direct member access. + */ +public class AuralProps { + + public int azimuth; + public String cueAfter; + public String cueBefore; + public int elevation; + public int pauseAfter; + public int pauseBefore; + public int pitch; + public int pitchRange; + public int playDuring; + public int richness; + public int speak; + public int speakHeader; + public int speakNumeral; + public int speakPunctuation; + public int speechRate; + public int stress; + public int voiceFamily; + public int volume; + +} diff --git a/src/java/org/apache/fop/layout/BackgroundProps.java b/src/java/org/apache/fop/layout/BackgroundProps.java new file mode 100644 index 000000000..6f41951a6 --- /dev/null +++ b/src/java/org/apache/fop/layout/BackgroundProps.java @@ -0,0 +1,69 @@ +/* + * $Id: BackgroundProps.java,v 1.5 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +import org.apache.fop.datatypes.Length; +import org.apache.fop.datatypes.ColorType; + +/** + * Store all background related properties on an FO. + * Public "structure" allows direct member access. + */ +public class BackgroundProps { + + public int backAttachment; + public ColorType backColor; + public String backImage; + public int backRepeat; + public Length backPosHorizontal; + public Length backPosVertical; + +} diff --git a/src/java/org/apache/fop/layout/BorderAndPadding.java b/src/java/org/apache/fop/layout/BorderAndPadding.java new file mode 100644 index 000000000..f6ecd03ff --- /dev/null +++ b/src/java/org/apache/fop/layout/BorderAndPadding.java @@ -0,0 +1,210 @@ +/* + * $Id: BorderAndPadding.java,v 1.10 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.datatypes.CondLength; +import org.apache.fop.fo.properties.Constants; + +public class BorderAndPadding implements Cloneable { + + public static final int BEFORE = 0; + public static final int AFTER = 1; + public static final int START = 2; + public static final int END = 3; + + public static final int TOP = BEFORE; + public static final int BOTTOM = AFTER; + public static final int LEFT = START; + public static final int RIGHT = END; + + private static class ResolvedCondLength implements Cloneable { + private int iLength; // Resolved length value + private boolean bDiscard; + + public ResolvedCondLength(CondLength length) { + bDiscard = length.isDiscard(); + iLength = length.getLengthValue(); + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + } + + /** + * Return a full copy of the BorderAndPadding information. This clones all + * padding and border information. + * @see java.lang.Object#clone() + */ + public Object clone() throws CloneNotSupportedException { + BorderAndPadding bp = (BorderAndPadding) super.clone(); + bp.padding = (ResolvedCondLength[]) padding.clone(); + bp.borderInfo = (BorderInfo[]) borderInfo.clone(); + for (int i = 0; i < padding.length; i++) { + if (padding[i] != null) { + bp.padding[i] = (ResolvedCondLength) padding[i].clone(); + } + if (borderInfo[i] != null) { + bp.borderInfo[i] = (BorderInfo) borderInfo[i].clone(); + } + } + return bp; + } + + public static class BorderInfo implements Cloneable { + private int mStyle; // Enum for border style + private ColorType mColor; // Border color + private ResolvedCondLength mWidth; + + BorderInfo(int style, CondLength width, ColorType color) { + mStyle = style; + mWidth = new ResolvedCondLength(width); + mColor = color; + } + + public Object clone() throws CloneNotSupportedException { + BorderInfo bi = (BorderInfo) super.clone(); + bi.mWidth = (ResolvedCondLength) mWidth.clone(); + // do we need to clone the Color too??? + return bi; + } + } + + private BorderInfo[] borderInfo = new BorderInfo[4]; + private ResolvedCondLength[] padding = new ResolvedCondLength[4]; + + public void setBorder(int side, int style, CondLength width, + ColorType color) { + borderInfo[side] = new BorderInfo(style, width, color); + } + + public void setPadding(int side, CondLength width) { + padding[side] = new ResolvedCondLength(width); + } + + public void setPaddingLength(int side, int iLength) { + padding[side].iLength = iLength; + } + + public void setBorderLength(int side, int iLength) { + borderInfo[side].mWidth.iLength = iLength; + } + + public int getBorderLeftWidth(boolean bDiscard) { + return getBorderWidth(LEFT, bDiscard); + } + + public int getBorderRightWidth(boolean bDiscard) { + return getBorderWidth(RIGHT, bDiscard); + } + + public int getBorderTopWidth(boolean bDiscard) { + return getBorderWidth(TOP, bDiscard); + } + + public int getBorderBottomWidth(boolean bDiscard) { + return getBorderWidth(BOTTOM, bDiscard); + } + + public int getPaddingLeft(boolean bDiscard) { + return getPadding(LEFT, bDiscard); + } + + public int getPaddingRight(boolean bDiscard) { + return getPadding(RIGHT, bDiscard); + } + + public int getPaddingBottom(boolean bDiscard) { + return getPadding(BOTTOM, bDiscard); + } + + public int getPaddingTop(boolean bDiscard) { + return getPadding(TOP, bDiscard); + } + + + public int getBorderWidth(int side, boolean bDiscard) { + if ((borderInfo[side] == null) + || (borderInfo[side].mStyle == Constants.NONE) + || (bDiscard && borderInfo[side].mWidth.bDiscard)) { + return 0; + } else { + return borderInfo[side].mWidth.iLength; + } + } + + public ColorType getBorderColor(int side) { + if (borderInfo[side] != null) { + return borderInfo[side].mColor; + } else { + return null; + } + } + + public int getBorderStyle(int side) { + if (borderInfo[side] != null) { + return borderInfo[side].mStyle; + } else { + return 0; + } + } + + public int getPadding(int side, boolean bDiscard) { + if ((padding[side] == null) || (bDiscard && padding[side].bDiscard)) { + return 0; + } else { + return padding[side].iLength; + } + } + +} diff --git a/src/java/org/apache/fop/layout/FontInfo.java b/src/java/org/apache/fop/layout/FontInfo.java new file mode 100644 index 000000000..dcde21770 --- /dev/null +++ b/src/java/org/apache/fop/layout/FontInfo.java @@ -0,0 +1,270 @@ +/* + * $Id: FontInfo.java,v 1.20 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +// Java +import java.util.Map; + +// FOP +import org.apache.fop.fonts.FontMetrics; + +/** + * The FontInfo for the layout and rendering of a fo document. + * This stores the list of available fonts that are setup by + * the renderer. The font name can be retrieved for the + * family style and weight. + *
+ * Currently font supported font-variant small-caps is not + * implemented. + */ +public class FontInfo { + + /** Default fallback key */ + public static final String DEFAULT_FONT = "any,normal,400"; + /** Normal font weight */ + public static final int NORMAL = 400; + /** Bold font weight */ + public static final int BOLD = 700; + + /** Map containing fonts that have been used */ + private Map usedFonts; + + /** look up a font-triplet to find a font-name */ + private Map triplets; + + /** look up a font-name to get a font (that implements FontMetrics at least) */ + private Map fonts; + + /** + * Main constructor + */ + public FontInfo() { + this.triplets = new java.util.HashMap(); + this.fonts = new java.util.HashMap(); + this.usedFonts = new java.util.HashMap(); + } + + /** + * Checks if the font setup is valid (At least the ultimate fallback font + * must be registered.) + * @return True if valid + */ + public boolean isSetupValid() { + return triplets.containsKey(DEFAULT_FONT); + } + + /** + * Adds a new font triplet. + * @param name internal key + * @param family font family name + * @param style font style (normal, italic, oblique...) + * @param weight font weight + */ + public void addFontProperties(String name, String family, String style, + int weight) { + /* + * add the given family, style and weight as a lookup for the font + * with the given name + */ + + String key = createFontKey(family, style, weight); + this.triplets.put(key, name); + } + + /** + * Adds font metrics for a specific font. + * @param name internal key + * @param metrics metrics to register + */ + public void addMetrics(String name, FontMetrics metrics) { + // add the given metrics as a font with the given name + + this.fonts.put(name, metrics); + } + + /** + * Lookup a font. + *
+ * Locate the font name for a given family, style and weight. + * The font name can then be used as a key as it is unique for + * the associated document. + * This also adds the font to the list of used fonts. + * @param family font family + * @param style font style + * @param weight font weight + * @return internal key + */ + public String fontLookup(String family, String style, + int weight) { + String key; + // first try given parameters + key = createFontKey(family, style, weight); + String f = (String)triplets.get(key); + if (f == null) { + // then adjust weight, favouring normal or bold + f = findAdjustWeight(family, style, weight); + + // then try any family with orig weight + if (f == null) { + key = createFontKey("any", style, weight); + f = (String)triplets.get(key); + } + + // then try any family with adjusted weight + if (f == null) { + f = findAdjustWeight(family, style, weight); + } + + // then use default + f = (String)triplets.get(DEFAULT_FONT); + + } + + usedFonts.put(f, fonts.get(f)); + return f; + } + + /** + * Find a font with a given family and style by trying + * different font weights according to the spec. + * @param family font family + * @param style font style + * @param weight font weight + * @return internal key + */ + public String findAdjustWeight(String family, String style, + int weight) { + String key; + String f = null; + int newWeight = weight; + if (newWeight < 400) { + while (f == null && newWeight > 0) { + newWeight -= 100; + key = createFontKey(family, style, newWeight); + f = (String)triplets.get(key); + } + } else if (newWeight == 500) { + key = createFontKey(family, style, 400); + f = (String)triplets.get(key); + } else if (newWeight > 500) { + while (f == null && newWeight < 1000) { + newWeight += 100; + key = createFontKey(family, style, newWeight); + f = (String)triplets.get(key); + } + newWeight = weight; + while (f == null && newWeight > 400) { + newWeight -= 100; + key = createFontKey(family, style, newWeight); + f = (String)triplets.get(key); + } + } + if (f == null) { + key = createFontKey(family, style, 400); + f = (String)triplets.get(key); + } + + return f; + } + + /** + * Determines if a particular font is available. + * @param family font family + * @param style font style + * @param weight font weight + * @return True if available + */ + public boolean hasFont(String family, String style, int weight) { + String key = createFontKey(family, style, weight); + return this.triplets.containsKey(key); + } + + /** + * Creates a key from the given strings. + * @param family font family + * @param style font style + * @param weight font weight + * @return internal key + */ + public static String createFontKey(String family, String style, + int weight) { + return family + "," + style + "," + weight; + } + + /** + * Gets a Map of all registred fonts. + * @return a read-only Map with font key/FontMetrics pairs + */ + public Map getFonts() { + return java.util.Collections.unmodifiableMap(this.fonts); + } + + /** + * This is used by the renderers to retrieve all the + * fonts used in the document. + * This is for embedded font or creating a list of used fonts. + * @return a read-only Map with font key/FontMetrics pairs + */ + public Map getUsedFonts() { + return this.usedFonts; + } + + /** + * Returns the FontMetrics for a particular font + * @param fontName internal key + * @return font metrics + */ + public FontMetrics getMetricsFor(String fontName) { + usedFonts.put(fontName, fonts.get(fontName)); + return (FontMetrics)fonts.get(fontName); + } +} + diff --git a/src/java/org/apache/fop/layout/FontState.java b/src/java/org/apache/fop/layout/FontState.java new file mode 100644 index 000000000..316675ca8 --- /dev/null +++ b/src/java/org/apache/fop/layout/FontState.java @@ -0,0 +1,206 @@ +/* + * $Id: FontState.java,v 1.23 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +import java.util.Map; + +import org.apache.fop.fonts.CodePointMapping; +import org.apache.fop.fonts.FontMetrics; + +/** + * This class holds font state information and provides access to the font + * metrics. + */ +public class FontState { + + private String fontName; + private int fontSize; + //private String fontFamily; + //private String fontStyle; + //private int fontWeight; + + /** + * normal or small-caps font + */ + //private int fontVariant; + + private FontMetrics metric; + + /** + * Main constructor + * @param key key of the font + * @param met font metrics + * @param fontSize font size + */ + public FontState(String key, FontMetrics met, int fontSize) { + this.fontName = key; + this.metric = met; + this.fontSize = fontSize; + } + + /** + * Returns the font's ascender. + * @return the ascender + */ + public int getAscender() { + return metric.getAscender(fontSize) / 1000; + } + + /** + * Returns the font's CapHeight. + * @return the capital height + */ + public int getCapHeight() { + return metric.getCapHeight(fontSize) / 1000; + } + + /** + * Returns the font's Descender. + * @return the descender + */ + public int getDescender() { + return metric.getDescender(fontSize) / 1000; + } + + /** + * Returns the font's name. + * @return the font name + */ + public String getFontName() { + return fontName; + } + + /** + * Returns the font size + * @return the font size + */ + public int getFontSize() { + return fontSize; + } + + /** + * Returns the XHeight + * @return the XHeight + */ + public int getXHeight() { + return metric.getXHeight(fontSize) / 1000; + } + + /** + * Returns the font's kerning table + * @return the kerning table + */ + public Map getKerning() { + Map ret = metric.getKerningInfo(); + if (ret != null) { + return ret; + } else { + return java.util.Collections.EMPTY_MAP; + } + } + + /** + * Returns the width of a character + * @param charnum character to look up + * @return width of the character + */ + public int getWidth(int charnum) { + // returns width of given character number in millipoints + return (metric.getWidth(charnum, fontSize) / 1000); + } + + /** + * Map a java character (unicode) to a font character. + * Default uses CodePointMapping. + * @param c character to map + * @return the mapped character + */ + public char mapChar(char c) { + + if (metric instanceof org.apache.fop.fonts.Font) { + return ((org.apache.fop.fonts.Font)metric).mapChar(c); + } + + // Use default CodePointMapping + char d = CodePointMapping.getMapping("WinAnsiEncoding").mapChar(c); + if (d != 0) { + c = d; + } else { + c = '#'; + } + + return c; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append('('); + /* + sbuf.append(fontFamily); + sbuf.append(',');*/ + sbuf.append(fontName); + sbuf.append(','); + sbuf.append(fontSize); + /* + sbuf.append(','); + sbuf.append(fontStyle); + sbuf.append(','); + sbuf.append(fontWeight);*/ + sbuf.append(')'); + return sbuf.toString(); + } +} + + + diff --git a/src/java/org/apache/fop/layout/HyphenationProps.java b/src/java/org/apache/fop/layout/HyphenationProps.java new file mode 100644 index 000000000..4f4fde8e7 --- /dev/null +++ b/src/java/org/apache/fop/layout/HyphenationProps.java @@ -0,0 +1,66 @@ +/* + * $Id: HyphenationProps.java,v 1.4 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all hyphenation related properties on an FO. + * Public "structure" allows direct member access. + */ +public class HyphenationProps { + + public int hyphenate; // Enum true or false: store as boolean! + public char hyphenationChar; + public int hyphenationPushCharacterCount; + public int hyphenationRemainCharacterCount; + public String language; // Language code or enum "NONE" + public String country; // Country code or enum "NONE" + +} diff --git a/src/java/org/apache/fop/layout/MarginInlineProps.java b/src/java/org/apache/fop/layout/MarginInlineProps.java new file mode 100644 index 000000000..139b28b91 --- /dev/null +++ b/src/java/org/apache/fop/layout/MarginInlineProps.java @@ -0,0 +1,66 @@ +/* + * $Id: MarginInlineProps.java,v 1.3 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all inline "margin" related properties + * Public "structure" allows direct member access. + */ +public class MarginInlineProps { + + public int marginTop; + public int marginBottom; + public int marginLeft; + public int marginRight; + public int spaceStart; + public int spaceEnd; + +} diff --git a/src/java/org/apache/fop/layout/MarginProps.java b/src/java/org/apache/fop/layout/MarginProps.java new file mode 100644 index 000000000..6435eb259 --- /dev/null +++ b/src/java/org/apache/fop/layout/MarginProps.java @@ -0,0 +1,68 @@ +/* + * $Id: MarginProps.java,v 1.4 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all block-level margin related properties on an FO. + * Public "structure" allows direct member access. + */ +public class MarginProps { + + public int marginTop; + public int marginBottom; + public int marginLeft; + public int marginRight; + public int spaceBefore; + public int spaceAfter; + public int startIndent; + public int endIndent; + +} diff --git a/src/java/org/apache/fop/layout/PageMaster.java b/src/java/org/apache/fop/layout/PageMaster.java new file mode 100644 index 000000000..928b67530 --- /dev/null +++ b/src/java/org/apache/fop/layout/PageMaster.java @@ -0,0 +1,68 @@ +/* + * $Id: PageMaster.java,v 1.15 2003/03/06 22:19:16 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +import org.apache.fop.area.PageViewport; + +public class PageMaster { + + private PageViewport pageVP; + + public PageMaster(PageViewport pageVP) { + this.pageVP = pageVP; + } + + // make a clone of the master + public PageViewport makePage() { + return (PageViewport)pageVP.clone(); + } + +} diff --git a/src/java/org/apache/fop/layout/RelativePositionProps.java b/src/java/org/apache/fop/layout/RelativePositionProps.java new file mode 100644 index 000000000..9ad73da3b --- /dev/null +++ b/src/java/org/apache/fop/layout/RelativePositionProps.java @@ -0,0 +1,68 @@ +/* + * $Id: RelativePositionProps.java,v 1.2 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * Store all hyphenation related properties on an FO. + * Public "structure" allows direct member access. + */ +public class RelativePositionProps { + + public int marginTop; + public int marginBottom; + public int marginLeft; + public int marginRight; + public int spaceBefore; + public int spaceAfter; + public int startIndent; + public int endIndent; + +} diff --git a/src/java/org/apache/fop/layout/TextState.java b/src/java/org/apache/fop/layout/TextState.java new file mode 100644 index 000000000..429800ab1 --- /dev/null +++ b/src/java/org/apache/fop/layout/TextState.java @@ -0,0 +1,107 @@ +/* + * $Id: TextState.java,v 1.6 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout; + +/** + * This class holds information about text-decoration. + */ +public class TextState { + + private boolean underlined; + private boolean overlined; + private boolean linethrough; + + /** + * @return true if text should be underlined + */ + public boolean getUnderlined() { + return underlined; + } + + /** + * Set text as underlined. + * @param ul true if underline should be enabled + */ + public void setUnderlined(boolean ul) { + this.underlined = ul; + } + + /** + * @return true if text should be overlined + */ + public boolean getOverlined() { + return overlined; + } + + /** + * Set text as overlined. + * @param ol true if overline should be enabled + */ + public void setOverlined(boolean ol) { + this.overlined = ol; + } + + /** + * @return true if text should have a line through the middle + */ + public boolean getLineThrough() { + return linethrough; + } + + /** + * Controls if text should have a line through the middle. + * @param lt true if line through should be enabled + */ + public void setLineThrough(boolean lt) { + this.linethrough = lt; + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/ByteVector.java b/src/java/org/apache/fop/layout/hyphenation/ByteVector.java new file mode 100644 index 000000000..0efb55f9a --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/ByteVector.java @@ -0,0 +1,158 @@ +/* + * $Id: ByteVector.java,v 1.5 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.io.Serializable; + +/** + * This class implements a simple byte vector with access to the + * underlying array. + * + * @author Carlos Villegas + */ +public class ByteVector implements Serializable { + + /** + * Capacity increment size + */ + private static final int DEFAULT_BLOCK_SIZE = 2048; + private int blockSize; + + /** + * The encapsulated array + */ + private byte[] array; + + /** + * Points to next free item + */ + private int n; + + public ByteVector() { + this(DEFAULT_BLOCK_SIZE); + } + + public ByteVector(int capacity) { + if (capacity > 0) { + blockSize = capacity; + } else { + blockSize = DEFAULT_BLOCK_SIZE; + } + array = new byte[blockSize]; + n = 0; + } + + public ByteVector(byte[] a) { + blockSize = DEFAULT_BLOCK_SIZE; + array = a; + n = 0; + } + + public ByteVector(byte[] a, int capacity) { + if (capacity > 0) { + blockSize = capacity; + } else { + blockSize = DEFAULT_BLOCK_SIZE; + } + array = a; + n = 0; + } + + public byte[] getArray() { + return array; + } + + /** + * return number of items in array + */ + public int length() { + return n; + } + + /** + * returns current capacity of array + */ + public int capacity() { + return array.length; + } + + public void put(int index, byte val) { + array[index] = val; + } + + public byte get(int index) { + return array[index]; + } + + /** + * This is to implement memory allocation in the array. Like malloc(). + */ + public int alloc(int size) { + int index = n; + int len = array.length; + if (n + size >= len) { + byte[] aux = new byte[len + blockSize]; + System.arraycopy(array, 0, aux, 0, len); + array = aux; + } + n += size; + return index; + } + + public void trimToSize() { + if (n < array.length) { + byte[] aux = new byte[n]; + System.arraycopy(array, 0, aux, 0, n); + array = aux; + } + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/CharVector.java b/src/java/org/apache/fop/layout/hyphenation/CharVector.java new file mode 100644 index 000000000..c4575b4ab --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/CharVector.java @@ -0,0 +1,168 @@ +/* + * $Id: CharVector.java,v 1.5 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.io.Serializable; + +/** + * This class implements a simple char vector with access to the + * underlying array. + * + * @author Carlos Villegas + */ +public class CharVector implements Cloneable, Serializable { + + /** + * Capacity increment size + */ + private static final int DEFAULT_BLOCK_SIZE = 2048; + private int blockSize; + + /** + * The encapsulated array + */ + private char[] array; + + /** + * Points to next free item + */ + private int n; + + public CharVector() { + this(DEFAULT_BLOCK_SIZE); + } + + public CharVector(int capacity) { + if (capacity > 0) { + blockSize = capacity; + } else { + blockSize = DEFAULT_BLOCK_SIZE; + } + array = new char[blockSize]; + n = 0; + } + + public CharVector(char[] a) { + blockSize = DEFAULT_BLOCK_SIZE; + array = a; + n = a.length; + } + + public CharVector(char[] a, int capacity) { + if (capacity > 0) { + blockSize = capacity; + } else { + blockSize = DEFAULT_BLOCK_SIZE; + } + array = a; + n = a.length; + } + + /** + * Reset Vector but don't resize or clear elements + */ + public void clear() { + n = 0; + } + + public Object clone() { + CharVector cv = new CharVector((char[])array.clone(), blockSize); + cv.n = this.n; + return cv; + } + + public char[] getArray() { + return array; + } + + /** + * return number of items in array + */ + public int length() { + return n; + } + + /** + * returns current capacity of array + */ + public int capacity() { + return array.length; + } + + public void put(int index, char val) { + array[index] = val; + } + + public char get(int index) { + return array[index]; + } + + public int alloc(int size) { + int index = n; + int len = array.length; + if (n + size >= len) { + char[] aux = new char[len + blockSize]; + System.arraycopy(array, 0, aux, 0, len); + array = aux; + } + n += size; + return index; + } + + public void trimToSize() { + if (n < array.length) { + char[] aux = new char[n]; + System.arraycopy(array, 0, aux, 0, n); + array = aux; + } + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/Hyphen.java b/src/java/org/apache/fop/layout/hyphenation/Hyphen.java new file mode 100644 index 000000000..56fe33ce7 --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/Hyphen.java @@ -0,0 +1,102 @@ +/* + * $Id: Hyphen.java,v 1.4 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.io.Serializable; + +/** + * This class represents a hyphen. A 'full' hyphen is made of 3 parts: + * the pre-break text, post-break text and no-break. If no line-break + * is generated at this position, the no-break text is used, otherwise, + * pre-break and post-break are used. Typically, pre-break is equal to + * the hyphen character and the others are empty. However, this general + * scheme allows support for cases in some languages where words change + * spelling if they're split across lines, like german's 'backen' which + * hyphenates 'bak-ken'. BTW, this comes from TeX. + * + * @author Carlos Villegas + */ + +public class Hyphen implements Serializable { + public String preBreak; + public String noBreak; + public String postBreak; + + Hyphen(String pre, String no, String post) { + preBreak = pre; + noBreak = no; + postBreak = post; + } + + Hyphen(String pre) { + preBreak = pre; + noBreak = null; + postBreak = null; + } + + public String toString() { + if (noBreak == null + && postBreak == null + && preBreak != null + && preBreak.equals("-")) { + return "-"; + } + StringBuffer res = new StringBuffer("{"); + res.append(preBreak); + res.append("}{"); + res.append(postBreak); + res.append("}{"); + res.append(noBreak); + res.append('}'); + return res.toString(); + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/Hyphenation.java b/src/java/org/apache/fop/layout/hyphenation/Hyphenation.java new file mode 100644 index 000000000..c8ffaabec --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/Hyphenation.java @@ -0,0 +1,117 @@ +/* + * $Id: Hyphenation.java,v 1.4 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +/** + * This class represents a hyphenated word. + * + * @author Carlos Villegas + */ +public class Hyphenation { + + private int[] hyphenPoints; + private String word; + + /** + * number of hyphenation points in word + */ + private int len; + + /** + * rawWord as made of alternating strings and {@link Hyphen Hyphen} + * instances + */ + Hyphenation(String word, int[] points) { + this.word = word; + hyphenPoints = points; + len = points.length; + } + + /** + * @return the number of hyphenation points in the word + */ + public int length() { + return len; + } + + /** + * @return the pre-break text, not including the hyphen character + */ + public String getPreHyphenText(int index) { + return word.substring(0, hyphenPoints[index]); + } + + /** + * @return the post-break text + */ + public String getPostHyphenText(int index) { + return word.substring(hyphenPoints[index]); + } + + /** + * @return the hyphenation points + */ + public int[] getHyphenationPoints() { + return hyphenPoints; + } + + public String toString() { + StringBuffer str = new StringBuffer(); + int start = 0; + for (int i = 0; i < len; i++) { + str.append(word.substring(start, hyphenPoints[i]) + "-"); + start = hyphenPoints[i]; + } + str.append(word.substring(start)); + return str.toString(); + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/HyphenationException.java b/src/java/org/apache/fop/layout/hyphenation/HyphenationException.java new file mode 100644 index 000000000..4272ed955 --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/HyphenationException.java @@ -0,0 +1,66 @@ +/* + * $Id: HyphenationException.java,v 1.4 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +/** + * @author Carlos Villegas + * @todo Derive from FOPException + */ +public class HyphenationException extends Exception { + + /** + * @see java.lang.Throwable#Throwable(String) + */ + public HyphenationException(String msg) { + super(msg); + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/HyphenationTree.java b/src/java/org/apache/fop/layout/hyphenation/HyphenationTree.java new file mode 100644 index 000000000..7c6b633d5 --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/HyphenationTree.java @@ -0,0 +1,569 @@ +/* + * $Id: HyphenationTree.java,v 1.8 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This tree structure stores the hyphenation patterns in an efficient + * way for fast lookup. It provides the provides the method to + * hyphenate a word. + * + * @author Carlos Villegas + */ +public class HyphenationTree extends TernaryTree + implements PatternConsumer, Serializable { + + /** + * value space: stores the inteletter values + */ + protected ByteVector vspace; + + /** + * This map stores hyphenation exceptions + */ + protected HashMap stoplist; + + /** + * This map stores the character classes + */ + protected TernaryTree classmap; + + /** + * Temporary map to store interletter values on pattern loading. + */ + private transient TernaryTree ivalues; + + public HyphenationTree() { + stoplist = new HashMap(23); // usually a small table + classmap = new TernaryTree(); + vspace = new ByteVector(); + vspace.alloc(1); // this reserves index 0, which we don't use + } + + /** + * Packs the values by storing them in 4 bits, two values into a byte + * Values range is from 0 to 9. We use zero as terminator, + * so we'll add 1 to the value. + * @param values a string of digits from '0' to '9' representing the + * interletter values. + * @return the index into the vspace array where the packed values + * are stored. + */ + protected int packValues(String values) { + int i, n = values.length(); + int m = (n & 1) == 1 ? (n >> 1) + 2 : (n >> 1) + 1; + int offset = vspace.alloc(m); + byte[] va = vspace.getArray(); + for (i = 0; i < n; i++) { + int j = i >> 1; + byte v = (byte)((values.charAt(i) - '0' + 1) & 0x0f); + if ((i & 1) == 1) { + va[j + offset] = (byte)(va[j + offset] | v); + } else { + va[j + offset] = (byte)(v << 4); // big endian + } + } + va[m - 1 + offset] = 0; // terminator + return offset; + } + + protected String unpackValues(int k) { + StringBuffer buf = new StringBuffer(); + byte v = vspace.get(k++); + while (v != 0) { + char c = (char)((v >>> 4) - 1 + '0'); + buf.append(c); + c = (char)(v & 0x0f); + if (c == 0) { + break; + } + c = (char)(c - 1 + '0'); + buf.append(c); + v = vspace.get(k++); + } + return buf.toString(); + } + + /** + * Read hyphenation patterns from an XML file. + */ + public void loadPatterns(String filename) throws HyphenationException { + PatternParser pp = new PatternParser(this); + ivalues = new TernaryTree(); + + pp.parse(filename); + + // patterns/values should be now in the tree + // let's optimize a bit + trimToSize(); + vspace.trimToSize(); + classmap.trimToSize(); + + // get rid of the auxiliary map + ivalues = null; + } + + public String findPattern(String pat) { + int k = super.find(pat); + if (k >= 0) { + return unpackValues(k); + } + return ""; + } + + /** + * String compare, returns 0 if equal or + * t is a substring of s + */ + protected int hstrcmp(char[] s, int si, char[] t, int ti) { + for (; s[si] == t[ti]; si++, ti++) { + if (s[si] == 0) { + return 0; + } + } + if (t[ti] == 0) { + return 0; + } + return s[si] - t[ti]; + } + + protected byte[] getValues(int k) { + StringBuffer buf = new StringBuffer(); + byte v = vspace.get(k++); + while (v != 0) { + char c = (char)((v >>> 4) - 1); + buf.append(c); + c = (char)(v & 0x0f); + if (c == 0) { + break; + } + c = (char)(c - 1); + buf.append(c); + v = vspace.get(k++); + } + byte[] res = new byte[buf.length()]; + for (int i = 0; i < res.length; i++) { + res[i] = (byte)buf.charAt(i); + } + return res; + } + + /** + *

Search for all possible partial matches of word starting + * at index an update interletter values. In other words, it + * does something like:

+ * + * for(i=0; i + *

But it is done in an efficient way since the patterns are + * stored in a ternary tree. In fact, this is the whole purpose + * of having the tree: doing this search without having to test + * every single pattern. The number of patterns for languages + * such as English range from 4000 to 10000. Thus, doing thousands + * of string comparisons for each word to hyphenate would be + * really slow without the tree. The tradeoff is memory, but + * using a ternary tree instead of a trie, almost halves the + * the memory used by Lout or TeX. It's also faster than using + * a hash table

+ * @param word null terminated word to match + * @param index start index from word + * @param il interletter values array to update + */ + protected void searchPatterns(char[] word, int index, byte[] il) { + byte[] values; + int i = index; + char p, q; + char sp = word[i]; + p = root; + + while (p > 0 && p < sc.length) { + if (sc[p] == 0xFFFF) { + if (hstrcmp(word, i, kv.getArray(), lo[p]) == 0) { + values = getValues(eq[p]); // data pointer is in eq[] + int j = index; + for (int k = 0; k < values.length; k++) { + if (j < il.length && values[k] > il[j]) { + il[j] = values[k]; + } + j++; + } + } + return; + } + int d = sp - sc[p]; + if (d == 0) { + if (sp == 0) { + break; + } + sp = word[++i]; + p = eq[p]; + q = p; + + // look for a pattern ending at this position by searching for + // the null char ( splitchar == 0 ) + while (q > 0 && q < sc.length) { + if (sc[q] == 0xFFFF) { // stop at compressed branch + break; + } + if (sc[q] == 0) { + values = getValues(eq[q]); + int j = index; + for (int k = 0; k < values.length; k++) { + if (j < il.length && values[k] > il[j]) { + il[j] = values[k]; + } + j++; + } + break; + } else { + q = lo[q]; + + /** + * actually the code should be: + * q = sc[q] < 0 ? hi[q] : lo[q]; + * but java chars are unsigned + */ + } + } + } else { + p = d < 0 ? lo[p] : hi[p]; + } + } + } + + /** + * Hyphenate word and return a Hyphenation object. + * @param word the word to be hyphenated + * @param remainCharCount Minimum number of characters allowed + * before the hyphenation point. + * @param pushCharCount Minimum number of characters allowed after + * the hyphenation point. + * @return a {@link Hyphenation Hyphenation} object representing + * the hyphenated word or null if word is not hyphenated. + */ + public Hyphenation hyphenate(String word, int remainCharCount, + int pushCharCount) { + char[] w = word.toCharArray(); + return hyphenate(w, 0, w.length, remainCharCount, pushCharCount); + } + + /** + * Hyphenate word and return an array of hyphenation points. + * @param w char array that contains the word + * @param offset Offset to first character in word + * @param len Length of word + * @param remainCharCount Minimum number of characters allowed + * before the hyphenation point. + * @param pushCharCount Minimum number of characters allowed after + * the hyphenation point. + * @return a {@link Hyphenation Hyphenation} object representing + * the hyphenated word or null if word is not hyphenated. + */ + public Hyphenation hyphenate(char[] w, int offset, int len, + int remainCharCount, int pushCharCount) { + int i; + char[] word = new char[len + 3]; + + // normalize word + char[] c = new char[2]; + for (i = 1; i <= len; i++) { + c[0] = w[offset + i - 1]; + int nc = classmap.find(c, 0); + if (nc < 0) { // found a non-letter character, abort + return null; + } + word[i] = (char)nc; + } + int[] result = new int[len + 1]; + int k = 0; + + // check exception list first + String sw = new String(word, 1, len); + if (stoplist.containsKey(sw)) { + // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no = null) + ArrayList hw = (ArrayList)stoplist.get(sw); + int j = 0; + for (i = 0; i < hw.size(); i++) { + Object o = hw.get(i); + if (o instanceof String) { + j += ((String)o).length(); + if (j >= remainCharCount && j < (len - pushCharCount)) { + result[k++] = j; + } + } + } + } else { + // use algorithm to get hyphenation points + word[0] = '.'; // word start marker + word[len + 1] = '.'; // word end marker + word[len + 2] = 0; // null terminated + byte[] il = new byte[len + 3]; // initialized to zero + for (i = 0; i < len + 1; i++) { + searchPatterns(word, i, il); + } + + // hyphenation points are located where interletter value is odd + for (i = 0; i < len; i++) { + if (((il[i + 1] & 1) == 1) && i >= remainCharCount + && i <= (len - pushCharCount)) { + result[k++] = i; + } + } + } + + + if (k > 0) { + // trim result array + int[] res = new int[k]; + System.arraycopy(result, 0, res, 0, k); + return new Hyphenation(new String(w, offset, len), res); + } else { + return null; + } + } + + /** + * Add a character class to the tree. It is used by + * {@link PatternParser PatternParser} as callback to + * add character classes. Character classes define the + * valid word characters for hyphenation. If a word contains + * a character not defined in any of the classes, it is not hyphenated. + * It also defines a way to normalize the characters in order + * to compare them with the stored patterns. Usually pattern + * files use only lower case characters, in this case a class + * for letter 'a', for example, should be defined as "aA", the first + * character being the normalization char. + */ + public void addClass(String chargroup) { + if (chargroup.length() > 0) { + char equivChar = chargroup.charAt(0); + char[] key = new char[2]; + key[1] = 0; + for (int i = 0; i < chargroup.length(); i++) { + key[0] = chargroup.charAt(i); + classmap.insert(key, 0, equivChar); + } + } + } + + /** + * Add an exception to the tree. It is used by + * {@link PatternParser PatternParser} class as callback to + * store the hyphenation exceptions. + * @param word normalized word + * @param hyphenatedword a vector of alternating strings and + * {@link Hyphen hyphen} objects. + */ + public void addException(String word, ArrayList hyphenatedword) { + stoplist.put(word, hyphenatedword); + } + + /** + * Add a pattern to the tree. Mainly, to be used by + * {@link PatternParser PatternParser} class as callback to + * add a pattern to the tree. + * @param pattern the hyphenation pattern + * @param ivalue interletter weight values indicating the + * desirability and priority of hyphenating at a given point + * within the pattern. It should contain only digit characters. + * (i.e. '0' to '9'). + */ + public void addPattern(String pattern, String ivalue) { + int k = ivalues.find(ivalue); + if (k <= 0) { + k = packValues(ivalue); + ivalues.insert(ivalue, (char)k); + } + insert(pattern, (char)k); + } + + public void printStats() { + System.out.println("Value space size = " + + Integer.toString(vspace.length())); + super.printStats(); + + } + + public static void main(String[] argv) throws Exception { + HyphenationTree ht = null; + int minCharCount = 2; + BufferedReader in = + new BufferedReader(new java.io.InputStreamReader(System.in)); + while (true) { + System.out.print("l:\tload patterns from XML\n" + + "L:\tload patterns from serialized object\n" + + "s:\tset minimun character count\n" + + "w:\twrite hyphenation tree to object file\n" + + "h:\thyphenate\n" + + "f:\tfind pattern\n" + + "b:\tbenchmark\n" + + "q:\tquit\n\n" + + "Command:"); + String token = in.readLine().trim(); + if (token.equals("f")) { + System.out.print("Pattern: "); + token = in.readLine().trim(); + System.out.println("Values: " + ht.findPattern(token)); + } else if (token.equals("s")) { + System.out.print("Minimun value: "); + token = in.readLine().trim(); + minCharCount = Integer.parseInt(token); + } else if (token.equals("l")) { + ht = new HyphenationTree(); + System.out.print("XML file name: "); + token = in.readLine().trim(); + ht.loadPatterns(token); + } else if (token.equals("L")) { + ObjectInputStream ois = null; + System.out.print("Object file name: "); + token = in.readLine().trim(); + try { + ois = new ObjectInputStream(new FileInputStream(token)); + ht = (HyphenationTree)ois.readObject(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + //ignore + } + } + } + } else if (token.equals("w")) { + System.out.print("Object file name: "); + token = in.readLine().trim(); + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(new FileOutputStream(token)); + oos.writeObject(ht); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (oos != null) { + try { + oos.flush(); + } catch (IOException e) { + //ignore + } + try { + oos.close(); + } catch (IOException e) { + //ignore + } + } + } + } else if (token.equals("h")) { + System.out.print("Word: "); + token = in.readLine().trim(); + System.out.print("Hyphenation points: "); + System.out.println(ht.hyphenate(token, minCharCount, + minCharCount)); + } else if (token.equals("b")) { + if (ht == null) { + System.out.println("No patterns has been loaded."); + break; + } + System.out.print("Word list filename: "); + token = in.readLine().trim(); + long starttime = 0; + int counter = 0; + ; + try { + BufferedReader reader = + new BufferedReader(new FileReader(token)); + String line; + + starttime = System.currentTimeMillis(); + while ((line = reader.readLine()) != null) { + // System.out.print("\nline: "); + Hyphenation hyp = ht.hyphenate(line, minCharCount, + minCharCount); + if (hyp != null) { + String hword = hyp.toString(); + // System.out.println(line); + // System.out.println(hword); + } else { + // System.out.println("No hyphenation"); + } + counter++; + } + } catch (Exception ioe) { + System.out.println("Exception " + ioe); + ioe.printStackTrace(); + } + long endtime = System.currentTimeMillis(); + long result = endtime - starttime; + System.out.println(counter + " words in " + result + + " Millisekunden hyphenated"); + + } else if (token.equals("q")) { + break; + } + } + + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/Hyphenator.java b/src/java/org/apache/fop/layout/hyphenation/Hyphenator.java new file mode 100644 index 000000000..132365c43 --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/Hyphenator.java @@ -0,0 +1,312 @@ +/* + * $Id: Hyphenator.java,v 1.9 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.util.Hashtable; + +/** + * This class is the main entry point to the hyphenation package. + * You can use only the static methods or create an instance. + * + * @author Carlos Villegas + */ +public class Hyphenator { + + /**@todo Don't use statics */ + private static Hashtable hyphenTrees = new Hashtable(); + + private HyphenationTree hyphenTree = null; + private int remainCharCount = 2; + private int pushCharCount = 2; + private static boolean errorDump = false; + + public Hyphenator(String lang, String country, int leftMin, + int rightMin) { + hyphenTree = getHyphenationTree(lang, country); + remainCharCount = leftMin; + pushCharCount = rightMin; + } + + public static HyphenationTree getHyphenationTree(String lang, + String country) { + String key = lang; + // check whether the country code has been used + if (country != null && !country.equals("none")) { + key += "_" + country; + } + // first try to find it in the cache + if (hyphenTrees.containsKey(key)) { + return (HyphenationTree)hyphenTrees.get(key); + } + if (hyphenTrees.containsKey(lang)) { + return (HyphenationTree)hyphenTrees.get(lang); + } + + HyphenationTree hTree = getFopHyphenationTree(key); + if (hTree == null) { + String hyphenDir = "/hyph"; + if (hyphenDir != null) { + hTree = getUserHyphenationTree(key, hyphenDir); + } + } + // put it into the pattern cache + if (hTree != null) { + hyphenTrees.put(key, hTree); + } else { + /**@todo Proper logging please */ + //log.error("Couldn't find hyphenation pattern " + // + key); + } + return hTree; + } + + private static InputStream getResourceStream(String key) { + InputStream is = null; + // Try to use Context Class Loader to load the properties file. + try { + java.lang.reflect.Method getCCL = + Thread.class.getMethod("getContextClassLoader", new Class[0]); + if (getCCL != null) { + ClassLoader contextClassLoader = + (ClassLoader)getCCL.invoke(Thread.currentThread(), + new Object[0]); + is = contextClassLoader.getResourceAsStream("hyph/" + key + + ".hyp"); + } + } catch (Exception e) { + //ignore, fallback further down + } + + if (is == null) { + is = Hyphenator.class.getResourceAsStream("/hyph/" + key + + ".hyp"); + } + + return is; + } + + public static HyphenationTree getFopHyphenationTree(String key) { + HyphenationTree hTree = null; + ObjectInputStream ois = null; + InputStream is = null; + try { + is = getResourceStream(key); + if (is == null) { + if (key.length() == 5) { + is = getResourceStream(key.substring(0, 2)); + if (is != null) { + //log.error("Couldn't find hyphenation pattern " + // + key + // + "\nusing general language pattern " + // + key.substring(0, 2) + // + " instead."); + } else { + if (errorDump) { + //log.error("Couldn't find precompiled " + // + "fop hyphenation pattern " + // + key + ".hyp"); + } + return null; + } + } else { + if (errorDump) { + //log.error("Couldn't find precompiled " + // + "fop hyphenation pattern " + // + key + ".hyp"); + } + return null; + } + } + ois = new ObjectInputStream(is); + hTree = (HyphenationTree)ois.readObject(); + } catch (Exception e) { + /**@todo proper logging please */ + e.printStackTrace(); + } finally { + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + //log.error("can't close hyphenation object stream"); + } + } + } + return hTree; + } + + /** + * load tree from serialized file or xml file + * using configuration settings + */ + public static HyphenationTree getUserHyphenationTree(String key, + String hyphenDir) { + HyphenationTree hTree = null; + // I use here the following convention. The file name specified in + // the configuration is taken as the base name. First we try + // name + ".hyp" assuming a serialized HyphenationTree. If that fails + // we try name + ".xml", assumming a raw hyphenation pattern file. + + // first try serialized object + File hyphenFile = new File(hyphenDir, key + ".hyp"); + if (hyphenFile.exists()) { + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(new BufferedInputStream( + new FileInputStream(hyphenFile))); + hTree = (HyphenationTree)ois.readObject(); + } catch (Exception e) { + /**@todo Proper logging please */ + e.printStackTrace(); + } finally { + if (ois != null) { + try { + ois.close(); + } catch (IOException e) { + //ignore + } + } + } + return hTree; + } else { + + // try the raw XML file + hyphenFile = new File(hyphenDir, key + ".xml"); + if (hyphenFile.exists()) { + hTree = new HyphenationTree(); + if (errorDump) { + //log.error("reading " + hyphenDir + key + // + ".xml"); + } + try { + hTree.loadPatterns(hyphenFile.getPath()); + if (errorDump) { + System.out.println("Stats: "); + hTree.printStats(); + } + return hTree; + } catch (HyphenationException ex) { + if (errorDump) { + //log.error("Can't load user patterns " + // + "from xml file " + hyphenDir + // + key + ".xml"); + } + return null; + } + } else { + if (errorDump) { + //log.error("Tried to load " + // + hyphenFile.toString() + // + "\nCannot find compiled nor xml file for " + // + "hyphenation pattern" + key); + } + return null; + } + } + } + + public static Hyphenation hyphenate(String lang, String country, + String word, int leftMin, + int rightMin) { + HyphenationTree hTree = getHyphenationTree(lang, country); + if (hTree == null) { + //log.error("Error building hyphenation tree for language " + // + lang); + return null; + } + return hTree.hyphenate(word, leftMin, rightMin); + } + + public static Hyphenation hyphenate(String lang, String country, + char[] word, int offset, int len, + int leftMin, int rightMin) { + HyphenationTree hTree = getHyphenationTree(lang, country); + if (hTree == null) { + //log.error("Error building hyphenation tree for language " + // + lang); + return null; + } + return hTree.hyphenate(word, offset, len, leftMin, rightMin); + } + + public void setMinRemainCharCount(int min) { + remainCharCount = min; + } + + public void setMinPushCharCount(int min) { + pushCharCount = min; + } + + public void setLanguage(String lang, String country) { + hyphenTree = getHyphenationTree(lang, country); + } + + public Hyphenation hyphenate(char[] word, int offset, int len) { + if (hyphenTree == null) { + return null; + } + return hyphenTree.hyphenate(word, offset, len, remainCharCount, + pushCharCount); + } + + public Hyphenation hyphenate(String word) { + if (hyphenTree == null) { + return null; + } + return hyphenTree.hyphenate(word, remainCharCount, pushCharCount); + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/PatternConsumer.java b/src/java/org/apache/fop/layout/hyphenation/PatternConsumer.java new file mode 100644 index 000000000..5bb5de38f --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/PatternConsumer.java @@ -0,0 +1,89 @@ +/* + * $Id: PatternConsumer.java,v 1.5 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.util.ArrayList; + +/** + * This interface is used to connect the XML pattern file parser to + * the hyphenation tree. + * + * @author Carlos Villegas + */ +public interface PatternConsumer { + + /** + * Add a character class. + * A character class defines characters that are considered + * equivalent for the purpose of hyphenation (e.g. "aA"). It + * usually means to ignore case. + * @param chargroup character group + */ + void addClass(String chargroup); + + /** + * Add a hyphenation exception. An exception replaces the + * result obtained by the algorithm for cases for which this + * fails or the user wants to provide his own hyphenation. + * A hyphenatedword is a vector of alternating String's and + * {@link Hyphen Hyphen} instances + */ + void addException(String word, ArrayList hyphenatedword); + + /** + * Add hyphenation patterns. + * @param pattern the pattern + * @param values interletter values expressed as a string of + * digit characters. + */ + void addPattern(String pattern, String values); + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/PatternParser.java b/src/java/org/apache/fop/layout/hyphenation/PatternParser.java new file mode 100644 index 000000000..bfae07bfc --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/PatternParser.java @@ -0,0 +1,465 @@ +/* + * $Id: PatternParser.java,v 1.7 2003/03/06 22:19:14 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +// SAX +import org.xml.sax.XMLReader; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.Attributes; + +// Java +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.net.URL; + +/** + * A SAX document handler to read and parse hyphenation patterns + * from a XML file. + * + * @author Carlos Villegas + */ +public class PatternParser extends DefaultHandler implements PatternConsumer { + + XMLReader parser; + int currElement; + PatternConsumer consumer; + StringBuffer token; + ArrayList exception; + char hyphenChar; + String errMsg; + + static final int ELEM_CLASSES = 1; + static final int ELEM_EXCEPTIONS = 2; + static final int ELEM_PATTERNS = 3; + static final int ELEM_HYPHEN = 4; + + public PatternParser() throws HyphenationException { + token = new StringBuffer(); + parser = createParser(); + parser.setContentHandler(this); + parser.setErrorHandler(this); + hyphenChar = '-'; // default + + } + + public PatternParser(PatternConsumer consumer) + throws HyphenationException { + this(); + this.consumer = consumer; + } + + public void setConsumer(PatternConsumer consumer) { + this.consumer = consumer; + } + + public void parse(String filename) throws HyphenationException { + InputSource uri = fileInputSource(filename); + + try { + parser.parse(uri); + } catch (SAXException e) { + throw new HyphenationException(errMsg); + } catch (IOException e) { + throw new HyphenationException(e.getMessage()); + } catch (NullPointerException e) { + throw new HyphenationException("SAX parser not available"); + } + } + + /** + * creates a SAX parser, using the value of org.xml.sax.parser + * defaulting to org.apache.xerces.parsers.SAXParser + * + * @return the created SAX parser + */ + static XMLReader createParser() throws HyphenationException { + String parserClassName = System.getProperty("org.xml.sax.parser"); + if (parserClassName == null) { + parserClassName = "org.apache.xerces.parsers.SAXParser"; + } + // System.out.println("using SAX parser " + parserClassName); + + try { + return (XMLReader)Class.forName(parserClassName).newInstance(); + } catch (ClassNotFoundException e) { + throw new HyphenationException("Could not find " + + parserClassName); + } catch (InstantiationException e) { + throw new HyphenationException("Could not instantiate " + + parserClassName); + } catch (IllegalAccessException e) { + throw new HyphenationException("Could not access " + + parserClassName); + } catch (ClassCastException e) { + throw new HyphenationException(parserClassName + + " is not a SAX driver"); + } + } + + /** + * create an InputSource from a file name + * + * @param filename the name of the file + * @return the InputSource created + */ + protected static InputSource fileInputSource(String filename) + throws HyphenationException { + + /* this code adapted from James Clark's in XT */ + File file = new File(filename); + String path = file.getAbsolutePath(); + String fSep = System.getProperty("file.separator"); + if (fSep != null && fSep.length() == 1) { + path = path.replace(fSep.charAt(0), '/'); + } + if (path.length() > 0 && path.charAt(0) != '/') { + path = '/' + path; + } + try { + return new InputSource(new URL("file", null, path).toString()); + } catch (java.net.MalformedURLException e) { + throw new HyphenationException("unexpected MalformedURLException"); + } + } + + protected String readToken(StringBuffer chars) { + String word; + boolean space = false; + int i; + for (i = 0; i < chars.length(); i++) { + if (Character.isWhitespace(chars.charAt(i))) { + space = true; + } else { + break; + } + } + if (space) { + // chars.delete(0,i); + for (int countr = i; countr < chars.length(); countr++) { + chars.setCharAt(countr - i, chars.charAt(countr)); + } + chars.setLength(chars.length() - i); + if (token.length() > 0) { + word = token.toString(); + token.setLength(0); + return word; + } + } + space = false; + for (i = 0; i < chars.length(); i++) { + if (Character.isWhitespace(chars.charAt(i))) { + space = true; + break; + } + } + token.append(chars.toString().substring(0, i)); + // chars.delete(0,i); + for (int countr = i; countr < chars.length(); countr++) { + chars.setCharAt(countr - i, chars.charAt(countr)); + } + chars.setLength(chars.length() - i); + if (space) { + word = token.toString(); + token.setLength(0); + return word; + } + token.append(chars); + return null; + } + + protected static String getPattern(String word) { + StringBuffer pat = new StringBuffer(); + int len = word.length(); + for (int i = 0; i < len; i++) { + if (!Character.isDigit(word.charAt(i))) { + pat.append(word.charAt(i)); + } + } + return pat.toString(); + } + + protected ArrayList normalizeException(ArrayList ex) { + ArrayList res = new ArrayList(); + for (int i = 0; i < ex.size(); i++) { + Object item = ex.get(i); + if (item instanceof String) { + String str = (String)item; + StringBuffer buf = new StringBuffer(); + for (int j = 0; j < str.length(); j++) { + char c = str.charAt(j); + if (c != hyphenChar) { + buf.append(c); + } else { + res.add(buf.toString()); + buf.setLength(0); + char[] h = new char[1]; + h[0] = hyphenChar; + // we use here hyphenChar which is not necessarily + // the one to be printed + res.add(new Hyphen(new String(h), null, null)); + } + } + if (buf.length() > 0) { + res.add(buf.toString()); + } + } else { + res.add(item); + } + } + return res; + } + + protected String getExceptionWord(ArrayList ex) { + StringBuffer res = new StringBuffer(); + for (int i = 0; i < ex.size(); i++) { + Object item = ex.get(i); + if (item instanceof String) { + res.append((String)item); + } else { + if (((Hyphen)item).noBreak != null) { + res.append(((Hyphen)item).noBreak); + } + } + } + return res.toString(); + } + + protected static String getInterletterValues(String pat) { + StringBuffer il = new StringBuffer(); + String word = pat + "a"; // add dummy letter to serve as sentinel + int len = word.length(); + for (int i = 0; i < len; i++) { + char c = word.charAt(i); + if (Character.isDigit(c)) { + il.append(c); + i++; + } else { + il.append('0'); + } + } + return il.toString(); + } + + // + // DocumentHandler methods + // + + /** + * Start element. + */ + public void startElement(String uri, String local, String raw, + Attributes attrs) { + if (local.equals("hyphen-char")) { + String h = attrs.getValue("value"); + if (h != null && h.length() == 1) { + hyphenChar = h.charAt(0); + } + } else if (local.equals("classes")) { + currElement = ELEM_CLASSES; + } else if (local.equals("patterns")) { + currElement = ELEM_PATTERNS; + } else if (local.equals("exceptions")) { + currElement = ELEM_EXCEPTIONS; + exception = new ArrayList(); + } else if (local.equals("hyphen")) { + if (token.length() > 0) { + exception.add(token.toString()); + } + exception.add(new Hyphen(attrs.getValue("pre"), + attrs.getValue("no"), + attrs.getValue("post"))); + currElement = ELEM_HYPHEN; + } + token.setLength(0); + } + + public void endElement(String uri, String local, String raw) { + + if (token.length() > 0) { + String word = token.toString(); + switch (currElement) { + case ELEM_CLASSES: + consumer.addClass(word); + break; + case ELEM_EXCEPTIONS: + exception.add(word); + exception = normalizeException(exception); + consumer.addException(getExceptionWord(exception), + (ArrayList)exception.clone()); + break; + case ELEM_PATTERNS: + consumer.addPattern(getPattern(word), + getInterletterValues(word)); + break; + case ELEM_HYPHEN: + // nothing to do + break; + } + if (currElement != ELEM_HYPHEN) { + token.setLength(0); + } + } + if (currElement == ELEM_HYPHEN) { + currElement = ELEM_EXCEPTIONS; + } else { + currElement = 0; + } + + } + + /** + * Characters. + */ + public void characters(char ch[], int start, int length) { + StringBuffer chars = new StringBuffer(length); + chars.append(ch, start, length); + String word = readToken(chars); + while (word != null) { + // System.out.println("\"" + word + "\""); + switch (currElement) { + case ELEM_CLASSES: + consumer.addClass(word); + break; + case ELEM_EXCEPTIONS: + exception.add(word); + exception = normalizeException(exception); + consumer.addException(getExceptionWord(exception), + (ArrayList)exception.clone()); + exception.clear(); + break; + case ELEM_PATTERNS: + consumer.addPattern(getPattern(word), + getInterletterValues(word)); + break; + } + word = readToken(chars); + } + + } + + // + // ErrorHandler methods + // + + /** + * Warning. + */ + public void warning(SAXParseException ex) { + errMsg = "[Warning] " + getLocationString(ex) + ": " + + ex.getMessage(); + } + + /** + * Error. + */ + public void error(SAXParseException ex) { + errMsg = "[Error] " + getLocationString(ex) + ": " + ex.getMessage(); + } + + /** + * Fatal error. + */ + public void fatalError(SAXParseException ex) throws SAXException { + errMsg = "[Fatal Error] " + getLocationString(ex) + ": " + + ex.getMessage(); + throw ex; + } + + /** + * Returns a string of the location. + */ + private String getLocationString(SAXParseException ex) { + StringBuffer str = new StringBuffer(); + + String systemId = ex.getSystemId(); + if (systemId != null) { + int index = systemId.lastIndexOf('/'); + if (index != -1) { + systemId = systemId.substring(index + 1); + } + str.append(systemId); + } + str.append(':'); + str.append(ex.getLineNumber()); + str.append(':'); + str.append(ex.getColumnNumber()); + + return str.toString(); + + } // getLocationString(SAXParseException):String + + + // PatternConsumer implementation for testing purposes + public void addClass(String c) { + System.out.println("class: " + c); + } + + public void addException(String w, ArrayList e) { + System.out.println("exception: " + w + " : " + e.toString()); + } + + public void addPattern(String p, String v) { + System.out.println("pattern: " + p + " : " + v); + } + + public static void main(String[] args) throws Exception { + if (args.length > 0) { + PatternParser pp = new PatternParser(); + pp.setConsumer(pp); + pp.parse(args[0]); + } + } + +} diff --git a/src/java/org/apache/fop/layout/hyphenation/TernaryTree.java b/src/java/org/apache/fop/layout/hyphenation/TernaryTree.java new file mode 100644 index 000000000..28d91071c --- /dev/null +++ b/src/java/org/apache/fop/layout/hyphenation/TernaryTree.java @@ -0,0 +1,701 @@ +/* + * $Id: TernaryTree.java,v 1.7 2003/03/06 22:19:15 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layout.hyphenation; + +import java.util.Enumeration; +import java.util.Stack; +import java.io.Serializable; + +/** + *

Ternary Search Tree

+ * + *

A ternary search tree is a hibrid between a binary tree and + * a digital search tree (trie). Keys are limited to strings. + * A data value of type char is stored in each leaf node. + * It can be used as an index (or pointer) to the data. + * Branches that only contain one key are compressed to one node + * by storing a pointer to the trailer substring of the key. + * This class is intended to serve as base class or helper class + * to implement Dictionary collections or the like. Ternary trees + * have some nice properties as the following: the tree can be + * traversed in sorted order, partial matches (wildcard) can be + * implemented, retrieval of all keys within a given distance + * from the target, etc. The storage requirements are higher than + * a binary tree but a lot less than a trie. Performance is + * comparable with a hash table, sometimes it outperforms a hash + * function (most of the time can determine a miss faster than a hash).

+ * + *

The main purpose of this java port is to serve as a base for + * implementing TeX's hyphenation algorithm (see The TeXBook, + * appendix H). Each language requires from 5000 to 15000 hyphenation + * patterns which will be keys in this tree. The strings patterns + * are usually small (from 2 to 5 characters), but each char in the + * tree is stored in a node. Thus memory usage is the main concern. + * We will sacrify 'elegance' to keep memory requirenments to the + * minimum. Using java's char type as pointer (yes, I know pointer + * it is a forbidden word in java) we can keep the size of the node + * to be just 8 bytes (3 pointers and the data char). This gives + * room for about 65000 nodes. In my tests the english patterns + * took 7694 nodes and the german patterns 10055 nodes, + * so I think we are safe.

+ * + *

All said, this is a map with strings as keys and char as value. + * Pretty limited!. It can be extended to a general map by + * using the string representation of an object and using the + * char value as an index to an array that contains the object + * values.

+ * + * @author cav@uniscope.co.jp + */ + +public class TernaryTree implements Cloneable, Serializable { + + /** + * We use 4 arrays to represent a node. I guess I should have created + * a proper node class, but somehow Knuth's pascal code made me forget + * we now have a portable language with virtual memory management and + * automatic garbage collection! And now is kind of late, furthermore, + * if it ain't broken, don't fix it. + */ + + /** + * Pointer to low branch and to rest of the key when it is + * stored directly in this node, we don't have unions in java! + */ + protected char[] lo; + + /** + * Pointer to high branch. + */ + protected char[] hi; + + /** + * Pointer to equal branch and to data when this node is a string terminator. + */ + protected char[] eq; + + /** + *

The character stored in this node: splitchar + * Two special values are reserved:

+ *
  • 0x0000 as string terminator
  • + *
  • 0xFFFF to indicate that the branch starting at + * this node is compressed
+ *

This shouldn't be a problem if we give the usual semantics to + * strings since 0xFFFF is garanteed not to be an Unicode character.

+ */ + protected char[] sc; + + /** + * This vector holds the trailing of the keys when the branch is compressed. + */ + protected CharVector kv; + + protected char root; + protected char freenode; + protected int length; // number of items in tree + + protected static final int BLOCK_SIZE = 2048; // allocation size for arrays + + TernaryTree() { + init(); + } + + protected void init() { + root = 0; + freenode = 1; + length = 0; + lo = new char[BLOCK_SIZE]; + hi = new char[BLOCK_SIZE]; + eq = new char[BLOCK_SIZE]; + sc = new char[BLOCK_SIZE]; + kv = new CharVector(); + } + + /** + * Branches are initially compressed, needing + * one node per key plus the size of the string + * key. They are decompressed as needed when + * another key with same prefix + * is inserted. This saves a lot of space, + * specially for long keys. + */ + public void insert(String key, char val) { + // make sure we have enough room in the arrays + int len = key.length() + + 1; // maximum number of nodes that may be generated + if (freenode + len > eq.length) { + redimNodeArrays(eq.length + BLOCK_SIZE); + } + char strkey[] = new char[len--]; + key.getChars(0, len, strkey, 0); + strkey[len] = 0; + root = insert(root, strkey, 0, val); + } + + public void insert(char[] key, int start, char val) { + int len = strlen(key) + 1; + if (freenode + len > eq.length) { + redimNodeArrays(eq.length + BLOCK_SIZE); + } + root = insert(root, key, start, val); + } + + /** + * The actual insertion function, recursive version. + */ + private char insert(char p, char[] key, int start, char val) { + int len = strlen(key, start); + if (p == 0) { + // this means there is no branch, this node will start a new branch. + // Instead of doing that, we store the key somewhere else and create + // only one node with a pointer to the key + p = freenode++; + eq[p] = val; // holds data + length++; + hi[p] = 0; + if (len > 0) { + sc[p] = 0xFFFF; // indicates branch is compressed + lo[p] = (char)kv.alloc(len + + 1); // use 'lo' to hold pointer to key + strcpy(kv.getArray(), lo[p], key, start); + } else { + sc[p] = 0; + lo[p] = 0; + } + return p; + } + + if (sc[p] == 0xFFFF) { + // branch is compressed: need to decompress + // this will generate garbage in the external key array + // but we can do some garbage collection later + char pp = freenode++; + lo[pp] = lo[p]; // previous pointer to key + eq[pp] = eq[p]; // previous pointer to data + lo[p] = 0; + if (len > 0) { + sc[p] = kv.get(lo[pp]); + eq[p] = pp; + lo[pp]++; + if (kv.get(lo[pp]) == 0) { + // key completly decompressed leaving garbage in key array + lo[pp] = 0; + sc[pp] = 0; + hi[pp] = 0; + } else { + // we only got first char of key, rest is still there + sc[pp] = 0xFFFF; + } + } else { + // In this case we can save a node by swapping the new node + // with the compressed node + sc[pp] = 0xFFFF; + hi[p] = pp; + sc[p] = 0; + eq[p] = val; + length++; + return p; + } + } + char s = key[start]; + if (s < sc[p]) { + lo[p] = insert(lo[p], key, start, val); + } else if (s == sc[p]) { + if (s != 0) { + eq[p] = insert(eq[p], key, start + 1, val); + } else { + // key already in tree, overwrite data + eq[p] = val; + } + } else { + hi[p] = insert(hi[p], key, start, val); + } + return p; + } + + /** + * Compares 2 null terminated char arrays + */ + public static int strcmp(char[] a, int startA, char[] b, int startB) { + for (; a[startA] == b[startB]; startA++, startB++) { + if (a[startA] == 0) { + return 0; + } + } + return a[startA] - b[startB]; + } + + /** + * Compares a string with null terminated char array + */ + public static int strcmp(String str, char[] a, int start) { + int i, d, len = str.length(); + for (i = 0; i < len; i++) { + d = (int)str.charAt(i) - a[start + i]; + if (d != 0) { + return d; + } + if (a[start + i] == 0) { + return d; + } + } + if (a[start + i] != 0) { + return (int)-a[start + i]; + } + return 0; + + } + + public static void strcpy(char[] dst, int di, char[] src, int si) { + while (src[si] != 0) { + dst[di++] = src[si++]; + } + dst[di] = 0; + } + + public static int strlen(char[] a, int start) { + int len = 0; + for (int i = start; i < a.length && a[i] != 0; i++) { + len++; + } + return len; + } + + public static int strlen(char[] a) { + return strlen(a, 0); + } + + public int find(String key) { + int len = key.length(); + char strkey[] = new char[len + 1]; + key.getChars(0, len, strkey, 0); + strkey[len] = 0; + + return find(strkey, 0); + } + + public int find(char[] key, int start) { + int d; + char p = root; + int i = start; + char c; + + while (p != 0) { + if (sc[p] == 0xFFFF) { + if (strcmp(key, i, kv.getArray(), lo[p]) == 0) { + return eq[p]; + } else { + return -1; + } + } + c = key[i]; + d = c - sc[p]; + if (d == 0) { + if (c == 0) { + return eq[p]; + } + i++; + p = eq[p]; + } else if (d < 0) { + p = lo[p]; + } else { + p = hi[p]; + } + } + return -1; + } + + public boolean knows(String key) { + return (find(key) >= 0); + } + + // redimension the arrays + private void redimNodeArrays(int newsize) { + int len = newsize < lo.length ? newsize : lo.length; + char[] na = new char[newsize]; + System.arraycopy(lo, 0, na, 0, len); + lo = na; + na = new char[newsize]; + System.arraycopy(hi, 0, na, 0, len); + hi = na; + na = new char[newsize]; + System.arraycopy(eq, 0, na, 0, len); + eq = na; + na = new char[newsize]; + System.arraycopy(sc, 0, na, 0, len); + sc = na; + } + + public int size() { + return length; + } + + public Object clone() { + TernaryTree t = new TernaryTree(); + t.lo = (char[])this.lo.clone(); + t.hi = (char[])this.hi.clone(); + t.eq = (char[])this.eq.clone(); + t.sc = (char[])this.sc.clone(); + t.kv = (CharVector)this.kv.clone(); + t.root = this.root; + t.freenode = this.freenode; + t.length = this.length; + + return t; + } + + /** + * Recursively insert the median first and then the median of the + * lower and upper halves, and so on in order to get a balanced + * tree. The array of keys is assumed to be sorted in ascending + * order. + */ + protected void insertBalanced(String[] k, char[] v, int offset, int n) { + int m; + if (n < 1) { + return; + } + m = n >> 1; + + insert(k[m + offset], v[m + offset]); + insertBalanced(k, v, offset, m); + + insertBalanced(k, v, offset + m + 1, n - m - 1); + } + + + /** + * Balance the tree for best search performance + */ + public void balance() { + // System.out.print("Before root splitchar = "); System.out.println(sc[root]); + + int i = 0, n = length; + String[] k = new String[n]; + char[] v = new char[n]; + Iterator iter = new Iterator(); + while (iter.hasMoreElements()) { + v[i] = iter.getValue(); + k[i++] = (String)iter.nextElement(); + } + init(); + insertBalanced(k, v, 0, n); + + // With uniform letter distribution sc[root] should be around 'm' + // System.out.print("After root splitchar = "); System.out.println(sc[root]); + } + + /** + * Each node stores a character (splitchar) which is part of + * some key(s). In a compressed branch (one that only contain + * a single string key) the trailer of the key which is not + * already in nodes is stored externally in the kv array. + * As items are inserted, key substrings decrease. + * Some substrings may completely disappear when the whole + * branch is totally decompressed. + * The tree is traversed to find the key substrings actually + * used. In addition, duplicate substrings are removed using + * a map (implemented with a TernaryTree!). + * + */ + public void trimToSize() { + // first balance the tree for best performance + balance(); + + // redimension the node arrays + redimNodeArrays(freenode); + + // ok, compact kv array + CharVector kx = new CharVector(); + kx.alloc(1); + TernaryTree map = new TernaryTree(); + compact(kx, map, root); + kv = kx; + kv.trimToSize(); + } + + private void compact(CharVector kx, TernaryTree map, char p) { + int k; + if (p == 0) { + return; + } + if (sc[p] == 0xFFFF) { + k = map.find(kv.getArray(), lo[p]); + if (k < 0) { + k = kx.alloc(strlen(kv.getArray(), lo[p]) + 1); + strcpy(kx.getArray(), k, kv.getArray(), lo[p]); + map.insert(kx.getArray(), k, (char)k); + } + lo[p] = (char)k; + } else { + compact(kx, map, lo[p]); + if (sc[p] != 0) { + compact(kx, map, eq[p]); + } + compact(kx, map, hi[p]); + } + } + + + public Enumeration keys() { + return new Iterator(); + } + + public class Iterator implements Enumeration { + + /** + * current node index + */ + int cur; + + /** + * current key + */ + String curkey; + + private class Item implements Cloneable { + char parent; + char child; + + public Item() { + parent = 0; + child = 0; + } + + public Item(char p, char c) { + parent = p; + child = c; + } + + public Object clone() { + return new Item(parent, child); + } + + } + + /** + * Node stack + */ + Stack ns; + + /** + * key stack implemented with a StringBuffer + */ + StringBuffer ks; + + public Iterator() { + cur = -1; + ns = new Stack(); + ks = new StringBuffer(); + rewind(); + } + + public void rewind() { + ns.removeAllElements(); + ks.setLength(0); + cur = root; + run(); + } + + public Object nextElement() { + String res = new String(curkey); + cur = up(); + run(); + return res; + } + + public char getValue() { + if (cur >= 0) { + return eq[cur]; + } + return 0; + } + + public boolean hasMoreElements() { + return (cur != -1); + } + + /** + * traverse upwards + */ + private int up() { + Item i = new Item(); + int res = 0; + + if (ns.empty()) { + return -1; + } + + if (cur != 0 && sc[cur] == 0) { + return lo[cur]; + } + + boolean climb = true; + + while (climb) { + i = (Item)ns.pop(); + i.child++; + switch (i.child) { + case 1: + if (sc[i.parent] != 0) { + res = eq[i.parent]; + ns.push(i.clone()); + ks.append(sc[i.parent]); + } else { + i.child++; + ns.push(i.clone()); + res = hi[i.parent]; + } + climb = false; + break; + + case 2: + res = hi[i.parent]; + ns.push(i.clone()); + if (ks.length() > 0) { + ks.setLength(ks.length() - 1); // pop + } + climb = false; + break; + + default: + if (ns.empty()) { + return -1; + } + climb = true; + break; + } + } + return res; + } + + /** + * traverse the tree to find next key + */ + private int run() { + if (cur == -1) { + return -1; + } + + boolean leaf = false; + while (true) { + // first go down on low branch until leaf or compressed branch + while (cur != 0) { + if (sc[cur] == 0xFFFF) { + leaf = true; + break; + } + ns.push(new Item((char)cur, '\u0000')); + if (sc[cur] == 0) { + leaf = true; + break; + } + cur = lo[cur]; + } + if (leaf) { + break; + } + // nothing found, go up one node and try again + cur = up(); + if (cur == -1) { + return -1; + } + } + // The current node should be a data node and + // the key should be in the key stack (at least partially) + StringBuffer buf = new StringBuffer(ks.toString()); + if (sc[cur] == 0xFFFF) { + int p = lo[cur]; + while (kv.get(p) != 0) { + buf.append(kv.get(p++)); + } + } + curkey = buf.toString(); + return 0; + } + + } + + public void printStats() { + System.out.println("Number of keys = " + Integer.toString(length)); + System.out.println("Node count = " + Integer.toString(freenode)); + // System.out.println("Array length = " + Integer.toString(eq.length)); + System.out.println("Key Array length = " + + Integer.toString(kv.length())); + + /* + * for(int i=0; i. For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fo.flow.Marker; +import org.apache.fop.area.Area; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.PageViewport; +import org.apache.fop.fo.PropertyManager; + +import org.apache.avalon.framework.logger.Logger; + +import java.util.ListIterator; +import java.util.Map; + +/** + * The base class for all LayoutManagers. + */ +public abstract class AbstractLayoutManager implements LayoutProcessor { + protected FOUserAgent userAgent; + protected LayoutProcessor parentLM = null; + protected FObj fobj; + protected String foID = null; + protected Map markers = null; + + /** True if this LayoutManager has handled all of its content. */ + private boolean bFinished = false; + protected LayoutProcessor curChildLM = null; + protected ListIterator childLMiter; + protected boolean bInited = false; + + /** + * Abstract layout manager. + */ + public AbstractLayoutManager() { + } + + /** + * Set the FO object for this layout manager + * + * @param fo the fo for this layout manager + */ + public void setFObj(FObj fo) { + this.fobj = fo; + foID = fobj.getID(); + markers = fobj.getMarkers(); + childLMiter = new LMiter(fobj.getChildren()); + } + + /** + * Set the user agent. + * + * @param ua the user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + /** + * Get the user agent. + * + * @see org.apache.fop.layoutmgr.LayoutManager#getUserAgent() + */ + public FOUserAgent getUserAgent() { + return userAgent; + } + + protected Logger getLogger() { + return userAgent.getLogger(); + } + + public void setParent(LayoutProcessor lm) { + this.parentLM = lm; + } + + // /** + // * Ask the parent LayoutManager to add the current (full) area to the + // * appropriate parent area. + // * @param bFinished If true, this area is finished, either because it's + // * completely full or because there is no more content to put in it. + // * If false, we are in the middle of this area. This can happen, + // * for example, if we find floats in a line. We stop the current area, + // * and add it (temporarily) to its parent so that we can see if there + // * is enough space to place the float(s) anchored in the line. + // */ + // protected void flush(Area area, boolean bFinished) { + // if (area != null) { + // // area.setFinished(true); + // parentLM.addChild(area, bFinished); // ???? + // if (bFinished) { + // setCurrentArea(null); + // } + // } + // } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + */ + + + public boolean generatesInlineAreas() { + return false; + } + + /** + * Add a child area to the current area. If this causes the maximum + * dimension of the current area to be exceeded, the parent LM is called + * to add it. + */ + + /** + * Return currently active child LayoutManager or null if + * all children have finished layout. + * Note: child must implement LayoutManager! If it doesn't, skip it + * and print a warning. + */ + protected LayoutProcessor getChildLM() { + if (curChildLM != null && !curChildLM.isFinished()) { + return curChildLM; + } + while (childLMiter.hasNext()) { + curChildLM = (LayoutProcessor) childLMiter.next(); + curChildLM.setUserAgent(getUserAgent()); + curChildLM.setParent(this); + curChildLM.init(); + return curChildLM; + } + return null; + } + + protected boolean hasMoreLM(LayoutManager prevLM) { + // prevLM should = curChildLM + if (prevLM != curChildLM) { + //log.debug("AbstractLayoutManager.peekNextLM: " + + // "passed LM is not current child LM!"); + return false; + } + return !childLMiter.hasNext(); + } + + + /** + * Reset the layoutmanager "iterator" so that it will start + * with the passed Position's generating LM + * on the next call to getChildLM. + * @param pos a Position returned by a child layout manager + * representing a potential break decision. + * If pos is null, then back up to the first child LM. + */ + protected void reset(Position pos) { + //if (lm == null) return; + LayoutManager lm = (pos != null) ? pos.getLM() : null; + if (curChildLM != lm) { + // ASSERT curChildLM == (LayoutManager)childLMiter.previous() + if (childLMiter.hasPrevious() && curChildLM + != (LayoutManager) childLMiter.previous()) { + //log.error("LMiter problem!"); + } + while (curChildLM != lm && childLMiter.hasPrevious()) { + curChildLM.resetPosition(null); + curChildLM = (LayoutProcessor) childLMiter.previous(); + } + // Otherwise next returns same object + childLMiter.next(); + } + if (curChildLM != null) { + curChildLM.resetPosition(pos); + } + if (isFinished()) { + setFinished(false); + } + } + + public void resetPosition(Position resetPos) { + // if (resetPos == null) { + // reset(null); + // } + } + + + /** + * This method provides a hook for a LayoutManager to intialize traits + * for the areas it will create, based on Properties set on its FO. + */ + public void init() { + if (fobj != null && bInited == false) { + initProperties(fobj.getPropertyManager()); + bInited = true; + } + } + + /** + * This method provides a hook for a LayoutManager to intialize traits + * for the areas it will create, based on Properties set on its FO. + */ + protected void initProperties(PropertyManager pm) { + //log.debug("AbstractLayoutManager.initProperties"); + } + + + /** + * Tell whether this LayoutManager has handled all of its content. + * @return True if there are no more break possibilities, + * ie. the last one returned represents the end of the content. + */ + public boolean isFinished() { + return bFinished; + } + + public void setFinished(boolean fin) { + bFinished = fin; + } + + + /** + * Generate and return the next break possibility. + * Each layout manager must implement this. + * TODO: should this be abstract or is there some reasonable + * default implementation? + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + return null; + } + + + /** + * Return value indicating whether the next area to be generated could + * start a new line or flow area. + * In general, if can't break at the current level, delegate to + * the first child LM. + * NOTE: should only be called if the START_AREA flag is set in context, + * since the previous sibling LM must have returned a BreakPoss which + * does not allow break-after. + * QUESTION: in block-stacked areas, does this mean some kind of keep + * condition, or is it only used for inline-stacked areas? + * Default implementation always returns true. + */ + public boolean canBreakBefore(LayoutContext context) { + return true; + } + + + public void addAreas(PositionIterator posIter, LayoutContext context) { + } + + + public void getWordChars(StringBuffer sbChars, Position bp1, + Position bp2) { + } + + /* --------------------------------------------------------- + * PROVIDE NULL IMPLEMENTATIONS OF METHODS from LayoutManager + * interface which are declared abstract in AbstractLayoutManager. + * ---------------------------------------------------------*/ + public Area getParentArea(Area childArea) { + return null; + } + + protected void flush() { + } + + public void addChild(Area childArea) { + } + + /** + * Delegate getting the current page number to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public String getCurrentPageNumber() { + return parentLM.getCurrentPageNumber(); + } + + /** + * Delegate resolving the id reference to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public PageViewport resolveRefID(String ref) { + return parentLM.resolveRefID(ref); + } + + /** + * Add the id to the page. + * If the id string is not null then add the id to the current page. + */ + protected void addID() { + if (foID != null) { + addIDToPage(foID); + } + } + + /** + * Delegate adding id reference to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public void addIDToPage(String id) { + parentLM.addIDToPage(id); + } + + /** + * Delegate adding unresolved area to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public void addUnresolvedArea(String id, Resolveable res) { + parentLM.addUnresolvedArea(id, res); + } + + /** + * Add the markers when adding an area. + */ + protected void addMarkers(boolean start, boolean isfirst) { + // add markers + if (markers != null) { + addMarkerMap(markers, start, isfirst); + } + } + + /** + * Delegate adding marker to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public void addMarkerMap(Map marks, boolean start, boolean isfirst) { + parentLM.addMarkerMap(marks, start, isfirst); + } + + /** + * Delegate retrieve marker to the parent layout manager. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public Marker retrieveMarker(String name, int pos, int boundary) { + return parentLM.retrieveMarker(name, pos, boundary); + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java new file mode 100644 index 000000000..d681ec5d6 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java @@ -0,0 +1,343 @@ +/* + * $Id: BlockContainerLayoutManager.java,v 1.13 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.List; +import java.awt.geom.Rectangle2D; + +import org.apache.fop.area.Area; +import org.apache.fop.area.BlockViewport; +import org.apache.fop.area.Block; +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layout.AbsolutePositionProps; +import org.apache.fop.fo.properties.AbsolutePosition; +import org.apache.fop.fo.properties.Overflow; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.area.CTM; +import org.apache.fop.datatypes.FODimension; + +/** + * LayoutManager for a block FO. + */ +public class BlockContainerLayoutManager extends BlockStackingLayoutManager { + + private BlockViewport viewportBlockArea; + private Block curBlockArea; + + private List childBreaks = new java.util.ArrayList(); + + private AbsolutePositionProps abProps; + private FODimension relDims; + private CTM absoluteCTM; + private boolean clip = false; + private int overflow; + private PropertyManager propManager; + + /** + * Create a new block container layout manager. + */ + public BlockContainerLayoutManager() { + } + + public void setOverflow(int of) { + overflow = of; + } + + protected void initProperties(PropertyManager pm) { + propManager = pm; + + abProps = pm.getAbsolutePositionProps(); + if (abProps.absolutePosition == AbsolutePosition.ABSOLUTE) { + Rectangle2D rect = new Rectangle2D.Double(abProps.left, + abProps.top, abProps.right - abProps.left, + abProps.bottom - abProps.top); + relDims = new FODimension(0, 0); + absoluteCTM = pm.getCTMandRelDims(rect, relDims); + } + } + + protected int getRotatedIPD() { + PropertyList props = propManager.getProperties(); + int height = props.get("height").getLength().getValue(); + height = props.get("inline-progression-dimension.optimum").getLength().getValue(); + + return height; + } + + public BreakPoss getNextBreakPoss(LayoutContext context) { + + if (abProps.absolutePosition == AbsolutePosition.ABSOLUTE) { + return getAbsoluteBreakPoss(context); + } + + Rectangle2D rect = new Rectangle2D.Double(0, 0, context.getRefIPD(), + context.getStackLimit().opt); + relDims = new FODimension(0, 0); + absoluteCTM = propManager.getCTMandRelDims(rect, relDims); + double[] vals = absoluteCTM.toArray(); + + MinOptMax stackLimit; + int ipd = context.getRefIPD(); + boolean rotated = vals[0] == 0.0; + if (rotated) { + // rotated 90 degrees + stackLimit = new MinOptMax(1000000); + ipd = getRotatedIPD(); + absoluteCTM = new CTM(vals[0], vals[1], vals[2], vals[3], 0, 0); + } else { + if (vals[0] == -1.0) { + absoluteCTM = new CTM(vals[0], vals[1], vals[2], vals[3], 0, 0); + } + stackLimit = context.getStackLimit(); + } + + LayoutProcessor curLM ; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + while ((curLM = getChildLM()) != null) { + // Make break positions and return blocks! + // Set up a LayoutContext + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(stackLimit, + stackSize)); + childLC.setRefIPD(ipd); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + if (stackSize.opt > stackLimit.max) { + // reset to last break + if (lastPos != null) { + reset(lastPos.getPosition()); + } else { + curLM.resetPosition(null); + } + break; + } + lastPos = bp; + childBreaks.add(bp); + + childLC.setStackLimit(MinOptMax.subtract( + stackLimit, stackSize)); + } + } + if (!rotated) { + BreakPoss breakPoss; + breakPoss = new BreakPoss(new LeafPosition(this, + childBreaks.size() - 1)); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + } + setFinished(true); + if (rotated) { + BreakPoss breakPoss; + breakPoss = new BreakPoss(new LeafPosition(this, + childBreaks.size() - 1)); + breakPoss.setStackingSize(new MinOptMax(ipd)); + return breakPoss; + } + return null; + } + + public BreakPoss getAbsoluteBreakPoss(LayoutContext context) { + + LayoutProcessor curLM ; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + + int ipd = relDims.ipd; + + while ((curLM = getChildLM()) != null) { + // Make break positions and return blocks! + // Set up a LayoutContext + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(new MinOptMax(1000000)); + childLC.setRefIPD(ipd); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + childBreaks.add(bp); + } + } + } + setFinished(true); + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + // absolutely positioned areas do not contribute + // to the normal stacking + breakPoss.setStackingSize(new MinOptMax(0)); + + if (stackSize.opt > relDims.bpd) { + if (overflow == Overflow.HIDDEN) { + clip = true; + } else if (overflow == Overflow.ERROR_IF_OVERFLOW) { + getLogger().error("contents overflows block-container viewport: clipping"); + clip = true; + } + } + + return breakPoss; + } + + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + + addID(); + addMarkers(true, true); + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + flush(); + addMarkers(true, true); + + childBreaks.clear(); + viewportBlockArea = null; + curBlockArea = null; + } + + /** + * Get the parent area for children of this block container. + * This returns the current block container area + * and creates it if required. + * + * @see org.apache.fop.layoutmgr.LayoutManager#getParentArea(Area) + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + viewportBlockArea = new BlockViewport(); + if (abProps.absolutePosition == AbsolutePosition.ABSOLUTE) { + viewportBlockArea.setXOffset(abProps.left); + viewportBlockArea.setYOffset(abProps.top); + viewportBlockArea.setWidth(abProps.right - abProps.left); + viewportBlockArea.setHeight(abProps.bottom - abProps.top); + + viewportBlockArea.setCTM(absoluteCTM); + viewportBlockArea.setClip(clip); + } else { + double[] vals = absoluteCTM.toArray(); + boolean rotated = vals[0] == 0.0; + if (rotated) { + viewportBlockArea.setWidth(relDims.bpd); + viewportBlockArea.setHeight(getRotatedIPD()); + viewportBlockArea.setCTM(absoluteCTM); + viewportBlockArea.setClip(clip); + } else if (vals[0] == -1.0) { + // need to set bpd to actual size for rotation + // and stacking + viewportBlockArea.setWidth(relDims.ipd); + viewportBlockArea.setWidth(relDims.bpd); + viewportBlockArea.setCTM(absoluteCTM); + viewportBlockArea.setClip(clip); + } + } + + curBlockArea = new Block(); + viewportBlockArea.addBlock(curBlockArea); + + if (abProps.absolutePosition == AbsolutePosition.ABSOLUTE) { + viewportBlockArea.setPositioning(Block.ABSOLUTE); + } + + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(viewportBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the block container. + * + * @see org.apache.fop.layoutmgr.LayoutManager#addChild(Area) + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java new file mode 100644 index 000000000..16df9728a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java @@ -0,0 +1,349 @@ +/* + * $Id: BlockLayoutManager.java,v 1.32 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.ListIterator; +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.TextInfo; +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.LineArea; +import org.apache.fop.traits.LayoutProps; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +/** + * LayoutManager for a block FO. + */ +public class BlockLayoutManager extends BlockStackingLayoutManager { + + private Block curBlockArea; + + private LayoutProps layoutProps; + private BorderAndPadding borderProps; + private BackgroundProps backgroundProps; + + private int lead = 12000; + private int lineHeight = 14000; + private int follow = 2000; + + private int iStartPos = 0; + + protected List childBreaks = new java.util.ArrayList(); + + /** + * Iterator for Block layout. + * This iterator combines consecutive inline areas and + * creates a line layout manager. + * The use of this iterator means that it can be reset properly. + */ + protected class BlockLMiter extends LMiter { + + private ListIterator proxy; + + public BlockLMiter(ListIterator pr) { + super(null); + proxy = pr; + } + + protected boolean preLoadNext() { + while (proxy.hasNext()) { + LayoutProcessor lm = (LayoutProcessor) proxy.next(); + lm.setParent(BlockLayoutManager.this); + if (lm.generatesInlineAreas()) { + LineLayoutManager lineLM = createLineManager(lm); + listLMs.add(lineLM); + } else { + listLMs.add(lm); + } + if (curPos < listLMs.size()) { + return true; + } + } + return false; + } + + protected LineLayoutManager createLineManager( + LayoutManager firstlm) { + LayoutProcessor lm; + List inlines = new ArrayList(); + inlines.add(firstlm); + while (proxy.hasNext()) { + lm = (LayoutProcessor) proxy.next(); + lm.setParent(BlockLayoutManager.this); + if (lm.generatesInlineAreas()) { + inlines.add(lm); + } else { + proxy.previous(); + break; + } + } + LineLayoutManager child; + child = new LineLayoutManager(lineHeight, + lead, follow); + child.setUserAgent(getUserAgent()); + child.setFObj(fobj); + child.setLMiter(inlines.listIterator()); + return child; + + } + } + + public BlockLayoutManager() { + } + + /** + * Set the FO object for this layout manager + * + * @param fo the fo for this layout manager + */ + public void setFObj(FObj fo) { + super.setFObj(fo); + childLMiter = new BlockLMiter(childLMiter); + } + + public void setBlockTextInfo(TextInfo ti) { + lead = ti.fs.getAscender(); + follow = ti.fs.getDescender(); + lineHeight = ti.lineHeight; + } + + /** + * This method provides a hook for a LayoutManager to intialize traits + * for the areas it will create, based on Properties set on its FO. + */ + protected void initProperties(PropertyManager pm) { + layoutProps = pm.getLayoutProps(); + borderProps = pm.getBorderAndPadding(); + backgroundProps = pm.getBackgroundProps(); + } + + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + int ipd = context.getRefIPD(); + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + stackSize.add(layoutProps.spaceBefore.getSpace()); + + BreakPoss lastPos = null; + + while ((curLM = getChildLM()) != null) { + // Make break positions and return blocks! + // Set up a LayoutContext + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + // if line layout manager then set stack limit to ipd + // line LM actually generates a LineArea which is a block + if (curLM.generatesInlineAreas()) { + // set stackLimit for lines + childLC.setStackLimit(new MinOptMax(ipd/* - iIndents - iTextIndent*/)); + childLC.setRefIPD(ipd); + } else { + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + } + boolean over = false; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + if (curLM.generatesInlineAreas()) { + // Reset stackLimit for non-first lines + childLC.setStackLimit(new MinOptMax(ipd/* - iIndents*/)); + } else { + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + } + if (getChildLM() == null || over) { + if (getChildLM() == null) { + setFinished(true); + stackSize.add(layoutProps.spaceAfter.getSpace()); + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + } + setFinished(true); + BreakPoss breakPoss = new BreakPoss(new LeafPosition(this, -2)); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + + // if adjusted space before + double adjust = layoutContext.getSpaceAdjust(); + addBlockSpacing(adjust, layoutProps.spaceBefore.getSpace()); + + addID(); + addMarkers(true, true); + + LayoutProcessor childLM; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + if (lfp.getLeafPos() == -2) { + curBlockArea = null; + flush(); + return; + } + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + + addMarkers(false, true); + + flush(); + + // if adjusted space after + addBlockSpacing(adjust, layoutProps.spaceAfter.getSpace()); + + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + + // set traits + TraitSetter.addBorders(curBlockArea, borderProps); + TraitSetter.addBackground(curBlockArea, backgroundProps); + + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + curBlockArea.setWidth(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + public void addChild(Area childArea) { + if (curBlockArea != null) { + if (childArea instanceof LineArea) { + curBlockArea.addLineArea((LineArea) childArea); + } else { + curBlockArea.addBlock((Block) childArea); + } + } + } + + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + childBreaks.clear(); + iStartPos = 0; + } else { + //reset(resetPos); + LayoutManager lm = resetPos.getLM(); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java new file mode 100644 index 000000000..f2d525100 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -0,0 +1,165 @@ +/* + * $Id: BlockStackingLayoutManager.java,v 1.18 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.area.Area; +import org.apache.fop.area.BlockParent; +import org.apache.fop.area.Block; + +/** + * Base LayoutManager class for all areas which stack their child + * areas in the block-progression direction, such as Flow, Block, ListBlock. + */ +public abstract class BlockStackingLayoutManager extends AbstractLayoutManager { + /** + * Reference to FO whose areas it's managing or to the traits + * of the FO. + */ + protected LayoutProcessor curChildLM = null; + protected BlockParent parentArea = null; + + public BlockStackingLayoutManager() { + } + + private BreakCost evaluateBreakCost(Area parent, Area child) { + return new BreakCost(child, 0); + } + + /** return current area being filled + */ + protected BlockParent getCurrentArea() { + return this.parentArea; + } + + + /** + * Set the current area being filled. + */ + protected void setCurrentArea(BlockParent parentArea) { + this.parentArea = parentArea; + } + + protected MinOptMax resolveSpaceSpecifier(Area nextArea) { + SpaceSpecifier spaceSpec = new SpaceSpecifier(false); + // Area prevArea = getCurrentArea().getLast(); + // if (prevArea != null) { + // spaceSpec.addSpace(prevArea.getSpaceAfter()); + // } + // spaceSpec.addSpace(nextArea.getSpaceBefore()); + return spaceSpec.resolve(false); + } + + /** + * Add a block spacer for space before and space after a block. + * This adds an empty Block area that acts as a block space. + * + * @param adjust the adjustment value + * @param minoptmax the min/opt/max value of the spacing + */ + public void addBlockSpacing(double adjust, MinOptMax minoptmax) { + int sp = minoptmax.opt; + if (adjust > 0) { + sp = sp + (int)(adjust * (minoptmax.max - minoptmax.opt)); + } else { + sp = sp + (int)(adjust * (minoptmax.opt - minoptmax.min)); + } + if (sp != 0) { + Block spacer = new Block(); + spacer.setHeight(sp); + parentLM.addChild(spacer); + } + } + + /** + * Add the childArea to the passed area. + * Called by child LayoutManager when it has filled one of its areas. + * The LM should already have an Area in which to put the child. + * See if the area will fit in the current area. + * If so, add it. Otherwise initiate breaking. + * @param childArea the area to add: will be some block-stacked Area. + * @param parentArea the area in which to add the childArea + */ + protected void addChildToArea(Area childArea, + BlockParent parentArea) { + // This should be a block-level Area (Block in the generic sense) + if (!(childArea instanceof Block)) { + //log.error("Child not a Block in BlockStackingLM!"); + } + + MinOptMax spaceBefore = resolveSpaceSpecifier(childArea); + parentArea.addBlock((Block) childArea); + flush(); // hand off current area to parent + } + + + /** + * Add the childArea to the current area. + * Called by child LayoutManager when it has filled one of its areas. + * The LM should already have an Area in which to put the child. + * See if the area will fit in the current area. + * If so, add it. Otherwise initiate breaking. + * @param childArea the area to add: will be some block-stacked Area. + */ + public void addChild(Area childArea) { + addChildToArea(childArea, getCurrentArea()); + } + + /** + * Force current area to be added to parent area. + */ + protected void flush() { + if (getCurrentArea() != null) { + parentLM.addChild(getCurrentArea()); + } + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/BreakCost.java b/src/java/org/apache/fop/layoutmgr/BreakCost.java new file mode 100644 index 000000000..f60de105b --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BreakCost.java @@ -0,0 +1,90 @@ +/* + * $Id: BreakCost.java,v 1.4 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.area.Area; + + +/** + * Evaluate and store the cost of breaking an Area at a given point. + */ +public class BreakCost { + private Area breakArea; + private BreakPoss bp; + + private int cost; // Will be more complicated than this! + + public BreakCost(Area breakArea, int cost) { + this.breakArea = breakArea; + this.cost = cost; + } + + public BreakCost(BreakPoss bp, int cost) { + this.bp = bp; + this.cost = cost; + } + + BreakPoss getBP() { + return this.bp; + } + + Area getArea() { + return this.breakArea; + } + + int getCost() { + return this.cost; + } + + public BreakCost chooseLowest(BreakCost otherCost) { + return this; + } +} diff --git a/src/java/org/apache/fop/layoutmgr/BreakPoss.java b/src/java/org/apache/fop/layoutmgr/BreakPoss.java new file mode 100644 index 000000000..61184cbf8 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BreakPoss.java @@ -0,0 +1,293 @@ +/* + * $Id: BreakPoss.java,v 1.13 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.traits.LayoutProps; + +/** + * Represents a break possibility for the layout manager. + * Used to pass information between different levels of layout manager concerning + * the break positions. In an inline context, before and after are interpreted as + * start and end. + * The position field is opaque represents where the break occurs. It is a + * nested structure with one level for each layout manager involved in generating + * the BreakPoss.. + * @author Karen Lease + */ +public class BreakPoss { + + // --- Values for flags returned from lower level LM. --- + /** May break after */ + public static final int CAN_BREAK_AFTER = 0x01; + /** Last area generated by FO */ + public static final int ISLAST = 0x02; + /** First area generated by FO */ + public static final int ISFIRST = 0x04; + /** Forced break (ie LF) */ + public static final int FORCE = 0x08; + /** May break before */ + public static final int CAN_BREAK_BEFORE = 0x10; + /** has anchors */ + public static final int HAS_ANCHORS = 0x40; + /** + * Set this flag if all fo:character generated Areas would + * suppressed at the end or beginning of a line */ + public static final int ALL_ARE_SUPPRESS_AT_LB = 0x80; + /** This break possibility is a hyphenation */ + public static final int HYPHENATED = 0x100; + /** + * If this break possibility ends the line, all remaining characters + * in the lowest level text LM will be suppressed. + */ + public static final int REST_ARE_SUPPRESS_AT_LB = 0x200; + /** Next area for LM overflows */ + public static final int NEXT_OVERFLOWS = 0x400; + + /** The opaque position object used by m_lm to record its + * break position. + */ + private Position position; + + /** + * The size range in the stacking direction of the area which would be + * generated if this BreakPoss were used. + */ + private MinOptMax stackSize; + + /** + * Max height above and below the baseline. These are cumulative. + */ + private int lead; + // the max height of before and after alignment + private int total; + // middle alignment height for after + private int middle; + + /** Size in the non-stacking direction (perpendicular). */ + private MinOptMax nonStackSize; + + private long flags = 0; + private LayoutProps layoutProps = new LayoutProps(); + + /** Store space-after (or end) and space-before (or start) to be + * added if this break position is used. + */ + private SpaceSpecifier spaceSpecTrailing; + private SpaceSpecifier spaceSpecLeading; + + public BreakPoss(Position position) { + this(position, 0); + } + + public BreakPoss(Position position, long flags) { + this.position = position; + this.flags = flags; + } + + /** + * The top-level layout manager responsible for this break + */ + public LayoutProcessor getLayoutManager() { + return position.getLM(); + } + + // public void setLayoutManager(LayoutManager lm) { + // m_lm = lm; + // } + + /** + * An object representing the break position in this layout manager. + */ + public Position getPosition() { + return position; + } + + public void setPosition(Position pos) { + position = pos; + } + + public void setStackingSize(MinOptMax size) { + this.stackSize = size; + } + + public MinOptMax getStackingSize() { + return this.stackSize ; + } + + public void setNonStackingSize(MinOptMax size) { + this.nonStackSize = size; + } + + public MinOptMax getNonStackingSize() { + return this.nonStackSize ; + } + + public long getFlags() { + return flags; + } + + public void setFlag(int flagBit) { + setFlag(flagBit, true); + } + + public void setFlag(int flagBit, boolean bSet) { + if (bSet) { + flags |= flagBit; + } else { + flags &= ~flagBit; + } + } + + public boolean isLastArea() { + return ((flags & ISLAST) != 0); + } + + public boolean isFirstArea() { + return ((flags & ISFIRST) != 0); + } + + public boolean canBreakAfter() { + return ((flags & CAN_BREAK_AFTER) != 0); + } + + public boolean canBreakBefore() { + return ((flags & CAN_BREAK_BEFORE) != 0); + } + + public boolean couldEndLine() { + return ((flags & REST_ARE_SUPPRESS_AT_LB) != 0); + } + + public boolean isForcedBreak() { + return ((flags & FORCE) != 0); + } + + public boolean nextBreakOverflows() { + return ((flags & NEXT_OVERFLOWS) != 0); + } + + public boolean isSuppressible() { + return ((flags & ALL_ARE_SUPPRESS_AT_LB) != 0); + } + + public SpaceSpecifier getLeadingSpace() { + return spaceSpecLeading; + } + + public MinOptMax resolveLeadingSpace() { + if (spaceSpecLeading != null) { + return spaceSpecLeading.resolve(false); + } else { + return new MinOptMax(0); + } + } + + public SpaceSpecifier getTrailingSpace() { + return spaceSpecTrailing; + } + + public MinOptMax resolveTrailingSpace(boolean bEndsRefArea) { + if (spaceSpecTrailing != null) { + return spaceSpecTrailing.resolve(bEndsRefArea); + } else { + return new MinOptMax(0); + } + } + + + public void setLeadingSpace(SpaceSpecifier spaceSpecLeading) { + this.spaceSpecLeading = spaceSpecLeading; + } + + public void setTrailingSpace(SpaceSpecifier spaceSpecTrailing) { + this.spaceSpecTrailing = spaceSpecTrailing; + } + + public LayoutProps getLayoutProps() { + return layoutProps; + } + + public int getLead() { + return lead; + } + + public int getTotal() { + return total; + } + + public int getMiddle() { + return middle; + } + + /** + * set lead height of baseline positioned element + * @param ld new lead value + */ + public void setLead(int ld) { + lead = ld; + } + + /** + * Set total height of top or bottom aligned element + * @param t new total height + */ + public void setTotal(int t) { + total = t; + } + + /** + * Set distance below baseline of middle aligned element + * @param t new value + */ + public void setMiddle(int t) { + middle = t; + } +} diff --git a/src/java/org/apache/fop/layoutmgr/BreakPossPosIter.java b/src/java/org/apache/fop/layoutmgr/BreakPossPosIter.java new file mode 100644 index 000000000..7f5420a1e --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/BreakPossPosIter.java @@ -0,0 +1,107 @@ +/* + * $Id: BreakPossPosIter.java,v 1.10 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.List; + +/** + * Position iterator for break possibilities. + */ +public class BreakPossPosIter extends PositionIterator { + + private int iterCount; + + /** + * Main constructor + * @param bpList List of break possibilities + * @param startPos starting position + * @param endPos ending position + */ + public BreakPossPosIter(List bpList, int startPos, int endPos) { + super(bpList.listIterator(startPos)); + iterCount = endPos - startPos; + } + + // Check position < endPos + + /** + * @see org.apache.fop.layoutmgr.PositionIterator#checkNext() + */ + protected boolean checkNext() { + if (iterCount > 0) { + return super.checkNext(); + } else { + endIter(); + return false; + } + } + + /** + * @see java.util.Iterator#next() + */ + public Object next() { + --iterCount; + return super.next(); + } + + public BreakPoss getBP() { + return (BreakPoss) peekNext(); + } + + protected LayoutProcessor getLM(Object nextObj) { + return ((BreakPoss) nextObj).getLayoutManager(); + } + + protected Position getPos(Object nextObj) { + return ((BreakPoss) nextObj).getPosition(); + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java new file mode 100644 index 000000000..730ecc1a9 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/ContentLayoutManager.java @@ -0,0 +1,277 @@ +/* + * $Id: ContentLayoutManager.java,v 1.17 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fo.flow.Marker; +import org.apache.fop.area.Area; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.PageViewport; + +import org.apache.avalon.framework.logger.Logger; + +import java.util.List; +import java.util.Map; +import java.util.ArrayList; + +/** + * Content Layout Manager. + * For use with objects that contain inline areas such as + * leader use-content and title. + */ +public class ContentLayoutManager implements LayoutProcessor { + private FOUserAgent userAgent; + private Area holder; + private int stackSize; + private LayoutProcessor parentLM; + + /** + * Constructs a new ContentLayoutManager + * + * @param area The parent area + */ + public ContentLayoutManager(Area area) { + holder = area; + } + + /** + * Set the FO object for this layout manager + * + * @param fo the fo for this layout manager + */ + public void setFObj(FObj fo) { + } + + public void fillArea(LayoutProcessor curLM) { + + List childBreaks = new ArrayList(); + MinOptMax stack = new MinOptMax(); + int ipd = 1000000; + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(LayoutContext.NEW_AREA); + childLC.setLeadingSpace(new SpaceSpecifier(false)); + childLC.setTrailingSpace(new SpaceSpecifier(false)); + // set stackLimit for lines + childLC.setStackLimit(new MinOptMax(ipd)); + childLC.setRefIPD(ipd); + + int lineHeight = 14000; + int lead = 12000; + int follow = 2000; + + int halfLeading = (lineHeight - lead - follow) / 2; + // height before baseline + int lineLead = lead + halfLeading; + // maximum size of top and bottom alignment + int maxtb = follow + halfLeading; + // max size of middle alignment below baseline + int middlefollow = maxtb; + + while (!curLM.isFinished()) { + MinOptMax lastSize = null; + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + lastSize = bp.getStackingSize(); + childBreaks.add(bp); + + if (bp.getLead() > lineLead) { + lineLead = bp.getLead(); + } + if (bp.getTotal() > maxtb) { + maxtb = bp.getTotal(); + } + if (bp.getMiddle() > middlefollow) { + middlefollow = bp.getMiddle(); + } + } + if (lastSize != null) { + stack.add(lastSize); + } + } + + if (maxtb - lineLead > middlefollow) { + middlefollow = maxtb - lineLead; + } + + //if(holder instanceof InlineParent) { + // ((InlineParent)holder).setHeight(lineHeight); + //} + + LayoutContext lc = new LayoutContext(0); + lc.setBaseline(lineLead); + lc.setLineHeight(lineHeight); + + lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + lc.setLeadingSpace(new SpaceSpecifier(false)); + lc.setTrailingSpace(new SpaceSpecifier(false)); + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, 0, childBreaks.size()); + curLM.addAreas(breakPosIter, lc); + stackSize = stack.opt; + } + + public int getStackingSize() { + return stackSize; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public boolean generatesInlineAreas() { + return true; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public Area getParentArea(Area childArea) { + return holder; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void addChild(Area childArea) { + holder.addChild(childArea); + } + + /** + * Set the user agent. + * + * @param ua the user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#getUserAgent() + */ + public FOUserAgent getUserAgent() { + return userAgent; + } + + /** + * Returns the logger + * @return the logger + */ + protected Logger getLogger() { + return userAgent.getLogger(); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void setParent(LayoutProcessor lm) { + parentLM = lm; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public boolean canBreakBefore(LayoutContext lc) { + return false; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + return null; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public boolean isFinished() { + return false; + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void setFinished(boolean isFinished) { + //to be done + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void addAreas(PositionIterator posIter, LayoutContext context) { } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void init() { + //to be done + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void resetPosition(Position position) { + //to be done + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void getWordChars(StringBuffer sbChars, Position bp1, + Position bp2) { } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public String getCurrentPageNumber() { + return parentLM.getCurrentPageNumber(); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public PageViewport resolveRefID(String ref) { + return parentLM.resolveRefID(ref); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void addIDToPage(String id) { + parentLM.addIDToPage(id); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void addUnresolvedArea(String id, Resolveable res) { + parentLM.addUnresolvedArea(id, res); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public void addMarkerMap(Map marks, boolean start, boolean isfirst) { + parentLM.addMarkerMap(marks, start, isfirst); + } + + /** @see org.apache.fop.layoutmgr.LayoutManager */ + public Marker retrieveMarker(String name, int pos, int boundary) { + return parentLM.retrieveMarker(name, pos, boundary); + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java new file mode 100644 index 000000000..f9e850ea7 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java @@ -0,0 +1,207 @@ +/* + * $Id: FlowLayoutManager.java,v 1.21 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.flow.Marker; +import org.apache.fop.area.Area; +import org.apache.fop.area.BlockParent; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for an fo:flow object. + * Its parent LM is the PageLayoutManager. + * This LM is responsible for getting columns of the appropriate size + * and filling them with block-level areas generated by its children. + */ +public class FlowLayoutManager extends BlockStackingLayoutManager { + + /** List of break possibilities */ + protected List blockBreaks = new ArrayList(); + + /** Array of areas currently being filled stored by area class */ + private BlockParent[] currentAreas = new BlockParent[Area.CLASS_MAX]; + + private int iStartPos = 0; + + /** + * This is the top level layout manager. + * It is created by the PageSequence FO. + */ + public FlowLayoutManager() { + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#getNextBreakPoss(LayoutContext) + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + + // currently active LM + LayoutProcessor curLM; + MinOptMax stackSize = new MinOptMax(); + + while ((curLM = getChildLM()) != null) { + if (curLM.generatesInlineAreas()) { + getLogger().error("inline area not allowed under flow - ignoring"); + curLM.setFinished(true); + continue; + } + + // Make break positions and return page break + // Set up a LayoutContext + MinOptMax bpd = context.getStackLimit(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + boolean breakPage = false; + childLC.setStackLimit(MinOptMax.subtract(bpd, stackSize)); + childLC.setRefIPD(context.getRefIPD()); + + if (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + blockBreaks.add(bp); + // set stackLimit for remaining space + childLC.setStackLimit(MinOptMax.subtract(bpd, stackSize)); + + if (bp.isForcedBreak() || bp.nextBreakOverflows()) { + breakPage = true; + } + } + } + + // check the stack bpd and if greater than available + // height then go to the last best break and return + // break position + if (stackSize.opt > context.getStackLimit().opt) { + breakPage = true; + } + if (breakPage) { + return new BreakPoss( + new LeafPosition(this, blockBreaks.size() - 1)); + } + } + setFinished(true); + if (blockBreaks.size() > 0) { + return new BreakPoss( + new LeafPosition(this, blockBreaks.size() - 1)); + } + return null; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#addAreas(PositionIterator, LayoutContext) + */ + public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { + + LayoutProcessor childLM; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(blockBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + flush(); + } + + /** + * Add child area to a the correct container, depending on its + * area class. A Flow can fill at most one area container of any class + * at any one time. The actual work is done by BlockStackingLM. + * @param childArea child area to add + */ + public void addChild(Area childArea) { + addChildToArea(childArea, + this.currentAreas[childArea.getAreaClass()]); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#getParentArea(Area) + */ + public Area getParentArea(Area childArea) { + // Get an area from the Page + BlockParent parentArea = + (BlockParent) parentLM.getParentArea(childArea); + this.currentAreas[parentArea.getAreaClass()] = parentArea; + setCurrentArea(parentArea); + return parentArea; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#resetPosition(Position) + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } + + /** + * Retrieve marker is not allowed in the flow so this reports an + * error and returns null. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public Marker retrieveMarker(String name, int pos, int boundary) { + // error cannot retrieve markers in flow + getLogger().error("Cannot retrieve a marker from the flow"); + return null; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/HyphContext.java b/src/java/org/apache/fop/layoutmgr/HyphContext.java new file mode 100644 index 000000000..8d8f765dc --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/HyphContext.java @@ -0,0 +1,91 @@ +/* + * $Id: HyphContext.java,v 1.3 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +/** + * This class is used to pass information to the getNextBreakPoss() + * method concerning hyphenation. A reference to an instance of the + * class is contained in the LayoutContext object passed to each + * LayoutManager. It contains information concerning the hyphenation + * points in a word and the how many of those have previously been + * processed by a Layout Manager to generate size information. + */ +public class HyphContext { + private int[] hyphPoints; + private int currentOffset = 0; + private int currentIndex = 0; + + public HyphContext(int[] hyphPoints) { + this.hyphPoints = hyphPoints; + } + + public int getNextHyphPoint() { + for (; currentIndex < hyphPoints.length; currentIndex++) { + if (hyphPoints[currentIndex] > currentOffset) { + return (hyphPoints[currentIndex] - currentOffset); + } + } + return -1; // AT END! + } + + public boolean hasMoreHyphPoints() { + for (; currentIndex < hyphPoints.length; currentIndex++) { + if (hyphPoints[currentIndex] > currentOffset) { + return true; + } + } + return false; + } + + public void updateOffset(int iCharsProcessed) { + currentOffset += iCharsProcessed; + } +} diff --git a/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java new file mode 100644 index 000000000..6b59e92ee --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/InlineStackingLayoutManager.java @@ -0,0 +1,618 @@ +/* + * $Id: InlineStackingLayoutManager.java,v 1.13 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.Iterator; +import java.util.ListIterator; +import java.util.HashMap; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; +import org.apache.fop.traits.InlineProps; +import org.apache.fop.area.Area; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Space; + +/** + * LayoutManager for objects which stack children in the inline direction, + * such as Inline or Line + */ +public class InlineStackingLayoutManager extends AbstractLayoutManager { + + + private static class StackingIter extends PositionIterator { + + StackingIter(Iterator parentIter) { + super(parentIter); + } + + protected LayoutProcessor getLM(Object nextObj) { + return ((Position) nextObj).getPosition().getLM(); + } + + protected Position getPos(Object nextObj) { + return ((Position) nextObj).getPosition(); + } + + } + + + /** + * Size of any start or end borders and padding. + */ + private MinOptMax allocIPD = new MinOptMax(0); + + /** + * Size of border and padding in BPD (ie, before and after). + */ + private MinOptMax extraBPD; + + + private InlineProps inlineProps = null; + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Area currentArea; // LineArea or InlineParent + + private BreakPoss prevBP; + private LayoutContext childLC ; + + private LayoutManager lastChildLM = null; // Set when return last breakposs + private boolean bAreaCreated = false; + + /** Used to store previous content IPD for each child LM. */ + private HashMap hmPrevIPD = new HashMap(); + + /** + * Create an inline stacking layout manager. + * This is used for fo's that create areas that + * contain inline areas. + * + * @param fobj the formatting object that creates the area + * @param childLMiter the iterator for child areas + */ + public InlineStackingLayoutManager() { + } + + /** + * Set the FO object for this layout manager + * + * @param fo the fo for this layout manager + */ + public void setFObj(FObj fo) { + this.fobj = fo; + foID = fobj.getID(); + childLMiter = null; + } + + /** + * Set the iterator. + * + * @param iter the iterator for this LM + */ + public void setLMiter(ListIterator iter) { + childLMiter = iter; + } + + /** + * Check if this generates inline areas. + * This creates inline areas that contain other inline areas. + * + * @return true + */ + public boolean generatesInlineAreas() { + return true; + } + + /** + * Initialize properties for this layout manager. + * + * @param propMgr the property manager from the fo that created this manager + */ + protected void initProperties(PropertyManager propMgr) { + // super.initProperties(propMgr); + inlineProps = propMgr.getInlineProps(); + borderProps = propMgr.getBorderAndPadding(); + // Calculdate border and padding size in BPD + int iPad = borderProps.getPadding(BorderAndPadding.BEFORE, false); + iPad += borderProps.getBorderWidth(BorderAndPadding.BEFORE, + false); + iPad += borderProps.getPadding(BorderAndPadding.AFTER, false); + iPad += borderProps.getBorderWidth(BorderAndPadding.AFTER, false); + extraBPD = new MinOptMax(iPad); + + backgroundProps = propMgr.getBackgroundProps(); + } + + private MinOptMax getExtraIPD(boolean bNotFirst, boolean bNotLast) { + int iBP = borderProps.getPadding(BorderAndPadding.START, + bNotFirst); + iBP += borderProps.getBorderWidth(BorderAndPadding.START, + bNotFirst); + iBP += borderProps.getPadding(BorderAndPadding.END, bNotLast); + iBP += borderProps.getBorderWidth(BorderAndPadding.END, bNotLast); + return new MinOptMax(iBP); + } + + + protected boolean hasLeadingFence(boolean bNotFirst) { + int iBP = borderProps.getPadding(BorderAndPadding.START, + bNotFirst); + iBP += borderProps.getBorderWidth(BorderAndPadding.START, + bNotFirst); + return (iBP > 0); + } + + protected boolean hasTrailingFence(boolean bNotLast) { + int iBP = borderProps.getPadding(BorderAndPadding.END, bNotLast); + iBP += borderProps.getBorderWidth(BorderAndPadding.END, bNotLast); + return (iBP > 0); + } + + /** + * Reset position for returning next BreakPossibility. + * @param prevPos a Position returned by this layout manager + * representing a potential break decision. + */ + public void resetPosition(Position prevPos) { + if (prevPos != null) { + // ASSERT (prevPos.getLM() == this) + if (prevPos.getLM() != this) { + //getLogger().error( + // "InlineStackingLayoutManager.resetPosition: " + + // "LM mismatch!!!"); + } + // Back up the child LM Position + Position childPos = prevPos.getPosition(); + reset(childPos); + if (prevBP != null + && prevBP.getLayoutManager() != childPos.getLM()) { + childLC = null; + } + prevBP = new BreakPoss(childPos); + } else { + // Backup to start of first child layout manager + prevBP = null; + // super.resetPosition(prevPos); + reset(prevPos); + // If any areas created, we are restarting! + bAreaCreated = false; + } + // Do we need to reset some context like pending or prevContent? + // What about prevBP? + } + + /** + * Return value indicating whether the next area to be generated could + * start a new line. This should only be called in the "START" condition + * if a previous inline BP couldn't end the line. + * Return true if any space-start, border-start or padding-start, else + * propagate to first child LM + */ + public boolean canBreakBefore(LayoutContext context) { + if (inlineProps.spaceStart.getSpace().min > 0 || hasLeadingFence(false)) { + return true; + } + LayoutProcessor lm = getChildLM(); + if (lm != null) { + return lm.canBreakBefore(context); + } else { + return false; // ??? NO child LM? + } + } + + protected MinOptMax getPrevIPD(LayoutManager lm) { + return (MinOptMax) hmPrevIPD.get(lm); + } + + /** + * Clear the previous IPD calculation. + */ + protected void clearPrevIPD() { + hmPrevIPD.clear(); + } + + /** + * Get the next break position for this layout manager. + * The next break position will be an position within the + * areas return by the child inline layout managers. + * + * @param lc the layout context for finding breaks + * @return the next break position + */ + public BreakPoss getNextBreakPoss(LayoutContext lc) { + // Get a break from currently active child LM + BreakPoss bp = null; + LayoutProcessor curLM; + SpaceSpecifier leadingSpace = lc.getLeadingSpace(); + + if (lc.startsNewArea()) { + // First call to this LM in new parent "area", but this may + // not be the first area created by this inline + childLC = new LayoutContext(lc); + lc.getLeadingSpace().addSpace(inlineProps.spaceStart); + + // Check for "fence" + if (hasLeadingFence(!lc.isFirstArea())) { + // Reset leading space sequence for child areas + leadingSpace = new SpaceSpecifier(false); + } + // Reset state variables + clearPrevIPD(); // Clear stored prev content dimensions + } + + // We only do this loop more than once if a childLM returns + // a null BreakPoss, meaning it has nothing (more) to layout. + while ((curLM = getChildLM()) != null) { + + // ignore nested blocks for now + if (!curLM.generatesInlineAreas()) { + getLogger().warn("ignoring block inside inline fo"); + curLM.setFinished(true); + continue; + } + /* If first break for this child LM, set START_AREA flag + * and initialize pending space from previous LM sibling's + * trailing space specifiers. + */ + boolean bFirstChildBP = (prevBP == null + || prevBP.getLayoutManager() != curLM); + + initChildLC(childLC, prevBP, lc.startsNewArea(), + bFirstChildBP, leadingSpace); + if (lc.tryHyphenate()) { + childLC.setHyphContext(lc.getHyphContext()); + } + + if (((bp = curLM.getNextBreakPoss(childLC)) != null) + || (lc.tryHyphenate() + && !lc.getHyphContext().hasMoreHyphPoints())) { + break; + } + // If LM has no content, should it generate any area? If not, + // should trailing space from a previous area interact with + // leading space from a following area? + } + if (bp == null) { + setFinished(true); + return null; // There was no childLM with anything to layout + // Alternative is to return a BP with the isLast flag set + } else { + boolean bIsLast = false; + if (getChildLM() == null) { + bIsLast = true; + setFinished(true); + } else if (bp.couldEndLine()) { + /* Child LM ends with suppressible spaces. See if it could + * end this LM's area too. Child LM finish flag is NOT set! + */ + bIsLast = !hasMoreLM(bp.getLayoutManager()); + } + return makeBreakPoss(bp, lc, bIsLast); + } + } + + /** ATTENTION: ALSO USED BY LineLayoutManager! */ + protected void initChildLC(LayoutContext childLC, BreakPoss prevBP, + boolean bStartParent, boolean bFirstChildBP, + SpaceSpecifier leadingSpace) { + + childLC.setFlags(LayoutContext.NEW_AREA, + (bFirstChildBP || bStartParent)); + if (bStartParent) { + // Start of a new line area or inline parent area + childLC.setFlags(LayoutContext.FIRST_AREA, bFirstChildBP); + childLC.setLeadingSpace(leadingSpace); + } else if (bFirstChildBP) { + // Space-after sequence from previous "area" + childLC.setFlags(LayoutContext.FIRST_AREA, true); + childLC.setLeadingSpace(prevBP.getTrailingSpace()); + } else { + childLC.setLeadingSpace(null); + } + } + + + private BreakPoss makeBreakPoss(BreakPoss bp, LayoutContext lc, + boolean bIsLast) { + NonLeafPosition inlbp = new NonLeafPosition(this, bp.getPosition()); + BreakPoss myBP = new BreakPoss(inlbp, bp.getFlags()); + + myBP.setFlag(BreakPoss.ISFIRST, lc.isFirstArea()); + myBP.setFlag(BreakPoss.ISLAST, bIsLast); + + if (bIsLast) { + lastChildLM = bp.getLayoutManager(); + } + + // Update dimension information for our allocation area, + // including child areas + // generated by previous childLM which have completed layout + // Update pending area measure + // This includes all previous breakinfo + + MinOptMax bpDim = (MinOptMax) bp.getStackingSize().clone(); + MinOptMax prevIPD = updatePrevIPD(bp, prevBP, lc.startsNewArea(), + lc.isFirstArea()); + + if (lc.startsNewArea()) { + myBP.setLeadingSpace(lc.getLeadingSpace()); + } + + + // Add size of previous child areas which are finished + bpDim.add(prevIPD); + + SpaceSpecifier trailingSpace = bp.getTrailingSpace(); + if (hasTrailingFence(!bIsLast)) { + bpDim.add(bp.resolveTrailingSpace(false)); + trailingSpace = new SpaceSpecifier(false); + } else { + // Need this to avoid modifying pending space specifiers + // on previous BP from child as we use these on the next + // call in this LM + trailingSpace = (SpaceSpecifier) trailingSpace.clone(); + } + trailingSpace.addSpace(inlineProps.spaceEnd); + myBP.setTrailingSpace(trailingSpace); + + // Add start and end borders and padding + bpDim.add(getExtraIPD(!lc.isFirstArea(), !bIsLast)); + myBP.setStackingSize(bpDim); + myBP.setNonStackingSize( + MinOptMax.add(bp.getNonStackingSize(), extraBPD)); + + prevBP = bp; + // if (bIsLast) { + // setFinished(true); // Our last area, so indicate done + // } + return myBP; + } + + + /** ATTENTION: ALSO USED BY LineLayoutManager! */ + protected MinOptMax updatePrevIPD(BreakPoss bp, BreakPoss prevBP, + boolean bStartParent, boolean bFirstArea) { + MinOptMax prevIPD = new MinOptMax(0); + + if (bStartParent) { + if (hasLeadingFence(!bFirstArea)) { + // Space-start before first child area placed + prevIPD.add(bp.resolveLeadingSpace()); + } + hmPrevIPD.put(bp.getLayoutManager(), prevIPD); + } else { + // In case of reset to a previous position, it may already + // be calculated + prevIPD = (MinOptMax) hmPrevIPD.get(bp.getLayoutManager()); + if (prevIPD == null) { + // ASSERT(prevBP.getLayoutManager() != bp.getLayoutManager()); + /* This is first bp generated by child (in this parent area). + * Calculate space-start on this area in combination with any + * pending space-end with previous break. + * Corresponds to Space between two child areas. + */ + prevIPD = (MinOptMax) hmPrevIPD.get( + prevBP.getLayoutManager()); + prevIPD = MinOptMax.add(prevIPD, bp.resolveLeadingSpace()); + prevIPD.add(prevBP.getStackingSize()); + hmPrevIPD.put(bp.getLayoutManager(), prevIPD); + } + } + return prevIPD; + } + + public void getWordChars(StringBuffer sbChars, Position bp1, + Position bp2) { + Position endPos = ((NonLeafPosition) bp2).getPosition(); + Position prevPos = null; + if (bp1 != null) { + prevPos = ((NonLeafPosition) bp1).getPosition(); + if (prevPos.getLM() != endPos.getLM()) { + prevPos = null; + } + } + endPos.getLM().getWordChars(sbChars, prevPos, endPos); + } + + /****** + protected BreakableText getText(BreakPoss prevBP, BreakPoss lastBP) { + } + *****/ + + protected InlineParent createArea() { + return new InlineParent(); + } + + /** + * Generate and add areas to parent area. + * Set size of each area. This should only create and return one + * inline area for any inline parent area. + * + * @param parentIter Iterator over Position information returned + * by this LayoutManager. + * @param dSpaceAdjust Factor controlling how much extra space to add + * in order to justify the line. + */ + public void addAreas(PositionIterator parentIter, + LayoutContext context) { + InlineParent parent = createArea(); + parent.setHeight(context.getLineHeight()); + parent.setOffset(0); + setCurrentArea(parent); + + setChildContext(new LayoutContext(context)); // Store current value + + // If has fence, make a new leadingSS + /* How to know if first area created by this LM? Keep a count and + * reset it if getNextBreakPoss() is called again. + */ + if (hasLeadingFence(bAreaCreated)) { + getContext().setLeadingSpace(new SpaceSpecifier(false)); + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, + true); + } else { + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, + false); + } + + context.getLeadingSpace().addSpace(inlineProps.spaceStart); + + + // posIter iterates over positions returned by this LM + StackingIter childPosIter = new StackingIter(parentIter); + LayoutProcessor prevLM = null; + LayoutProcessor childLM ; + while ((childLM = childPosIter.getNextChildLM()) != null) { + //getContext().setTrailingSpace(new SpaceSpecifier(false)); + childLM.addAreas(childPosIter, getContext()); + getContext().setLeadingSpace(getContext().getTrailingSpace()); + getContext().setFlags(LayoutContext.RESOLVE_LEADING_SPACE, + true); + prevLM = childLM; + } + + /* If has trailing fence, resolve trailing space specs from descendants. + * Otherwise, propagate any trailing space specs to parent LM via + * the context object. + * If the last child LM called return ISLAST in the context object + * and it is the last child LM for this LM, then this must be + * the last area for the current LM also. + */ + boolean bIsLast = + (getContext().isLastArea() && prevLM == lastChildLM); + if (hasTrailingFence(bIsLast)) { + addSpace(getCurrentArea(), + getContext().getTrailingSpace().resolve(false), + getContext().getSpaceAdjust()); + context.setTrailingSpace(new SpaceSpecifier(false)); + } else { + // Propagate trailing space-spec sequence to parent LM in context + context.setTrailingSpace(getContext().getTrailingSpace()); + } + // Add own trailing space to parent context (or set on area?) + if (context.getTrailingSpace() != null) { + context.getTrailingSpace().addSpace(inlineProps.spaceEnd); + } + + // Add border and padding to current area and set flags (FIRST, LAST ...) + TraitSetter.setBorderPaddingTraits(getCurrentArea(), + borderProps, bAreaCreated, !bIsLast); + + if (borderProps != null) { + TraitSetter.addBorders(getCurrentArea(), borderProps); + } + if (backgroundProps != null) { + TraitSetter.addBackground(getCurrentArea(), backgroundProps); + } + + parentLM.addChild(getCurrentArea()); + context.setFlags(LayoutContext.LAST_AREA, bIsLast); + bAreaCreated = true; + } + + protected Area getCurrentArea() { + return currentArea; + } + + protected void setCurrentArea(Area area) { + currentArea = area; + } + + public void addChild(Area childArea) { + // Make sure childArea is inline area + if (childArea instanceof InlineArea) { + Area parent = getCurrentArea(); + if (getContext().resolveLeadingSpace()) { + addSpace(parent, + getContext().getLeadingSpace().resolve(false), + getContext().getSpaceAdjust()); + } + parent.addChild(childArea); + } + } + + protected void setChildContext(LayoutContext lc) { + childLC = lc; + } + + // Current child layout context + protected LayoutContext getContext() { + return childLC ; + } + + protected void addSpace(Area parentArea, MinOptMax spaceRange, + double dSpaceAdjust) { + if (spaceRange != null) { + int iAdjust = spaceRange.opt; + if (dSpaceAdjust > 0.0) { + // Stretch by factor + iAdjust += (int)((double)(spaceRange.max + - spaceRange.opt) * dSpaceAdjust); + } else if (dSpaceAdjust < 0.0) { + // Shrink by factor + iAdjust += (int)((double)(spaceRange.opt + - spaceRange.min) * dSpaceAdjust); + } + if (iAdjust != 0) { + //getLogger().debug("Add leading space: " + iAdjust); + Space ls = new Space(); + ls.setWidth(iAdjust); + parentArea.addChild(ls); + } + } + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/LMiter.java b/src/java/org/apache/fop/layoutmgr/LMiter.java new file mode 100644 index 000000000..abda1ecb8 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LMiter.java @@ -0,0 +1,139 @@ +/* + * $Id: LMiter.java,v 1.8 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.FObj; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +public class LMiter implements ListIterator { + + + private ListIterator baseIter; + private FObj curFO; + protected List listLMs; + protected int curPos = 0; + + public LMiter(ListIterator bIter) { + baseIter = bIter; + listLMs = new ArrayList(10); + } + + public boolean hasNext() { + return (curPos < listLMs.size()) ? true : preLoadNext(); + } + + protected boolean preLoadNext() { + // skip over child FObj's that don't add lms + while (baseIter != null && baseIter.hasNext()) { + Object theobj = baseIter.next(); + if (theobj instanceof FObj) { + FObj fobj = (FObj) theobj; + //listLMs.add(fobj.getLayoutManager()); + fobj.addLayoutManager(listLMs); + if (curPos < listLMs.size()) { + return true; + } + } + } + return false; + } + + public boolean hasPrevious() { + return (curPos > 0); + } + + public Object previous() throws NoSuchElementException { + if (curPos > 0) { + return listLMs.get(--curPos); + } else { + throw new NoSuchElementException(); + } + } + + public Object next() throws NoSuchElementException { + if (curPos < listLMs.size()) { + return listLMs.get(curPos++); + } else { + throw new NoSuchElementException(); + } + } + + public void remove() throws NoSuchElementException { + if (curPos > 0) { + listLMs.remove(--curPos); + // Note: doesn't actually remove it from the base! + } else { + throw new NoSuchElementException(); + } + } + + + public void add(Object o) throws UnsupportedOperationException { + throw new UnsupportedOperationException("LMiter doesn't support add"); + } + + public void set(Object o) throws UnsupportedOperationException { + throw new UnsupportedOperationException("LMiter doesn't support set"); + } + + public int nextIndex() { + return curPos; + } + + public int previousIndex() { + return curPos - 1; + } + +} diff --git a/src/java/org/apache/fop/layoutmgr/LayoutContext.java b/src/java/org/apache/fop/layoutmgr/LayoutContext.java new file mode 100644 index 000000000..6187ba9e9 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LayoutContext.java @@ -0,0 +1,258 @@ +/* + * $Id: LayoutContext.java,v 1.12 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + + +/** + * This class is used to pass information to the getNextBreakPoss() + * method. It is set up by higher level LM and used by lower level LM. + */ +public class LayoutContext { + /** + * Values for flags. + */ + public static final int LINEBREAK_AT_LF_ONLY = 0x01; + /** Generated break possibility is first in a new area */ + public static final int NEW_AREA = 0x02; + public static final int IPD_UNKNOWN = 0x04; + /** Signal to a Line LM that a higher level LM may provoke a change + * in the reference area, thus ref area IPD. The LineLM should return + * without looking for a line break. + */ + public static final int CHECK_REF_AREA = 0x08; + + /** + * If this flag is set, it indicates that any leading fo:character + * objects with suppress-at-line-break="suppress" should not generate + * areas. This is the case at the beginning of each new LineArea + * except the first. + */ + public static final int SUPPRESS_LEADING_SPACE = 0x10; + public static final int FIRST_AREA = 0x20; + public static final int TRY_HYPHENATE = 0x40; + public static final int LAST_AREA = 0x80; + + public static final int RESOLVE_LEADING_SPACE = 0x100; + + + public int flags; // Contains some set of flags defined above + /** + * Total available stacking dimension for a "galley-level" layout + * manager (Line or Flow). It is passed by the parent LM. For LineLM, + * the block LM determines this based on indent properties. + * These LM may wish to pass this information down to lower + * level LM to allow them to optimize returned break possibilities. + */ + MinOptMax stackLimit; + + + /** True if current top-level reference area is spanning. */ + boolean bIsSpan; + + /** inline-progression-dimension of nearest ancestor reference area */ + int refIPD; + + /** Current pending space-after or space-end from preceding area */ + SpaceSpecifier trailingSpace; + + /** Current pending space-before or space-start from ancestor areas */ + SpaceSpecifier leadingSpace; + + /** Current hyphenation context. May be null. */ + private HyphContext hyphContext = null; + + /** Stretch or shrink value when making areas. */ + private double ipdAdjust = 0.0; + + /** Stretch or shrink value when adding spaces. */ + private double dSpaceAdjust = 0.0; + + private int iLineHeight; + private int iBaseline; + + public LayoutContext(LayoutContext parentLC) { + this.flags = parentLC.flags; + this.refIPD = parentLC.refIPD; + this.stackLimit = null; // Don't reference parent MinOptMax! + this.leadingSpace = parentLC.leadingSpace; //??? + this.trailingSpace = parentLC.trailingSpace; //??? + this.hyphContext = parentLC.hyphContext; + this.dSpaceAdjust = parentLC.dSpaceAdjust; + this.iLineHeight = parentLC.iLineHeight; + this.iBaseline = parentLC.iBaseline; + // Copy other fields as necessary. Use clone??? + } + + public LayoutContext(int flags) { + this.flags = flags; + this.refIPD = 0; + stackLimit = new MinOptMax(0); + leadingSpace = null; + trailingSpace = null; + } + + public void setFlags(int flags) { + setFlags(flags, true); + } + + public void setFlags(int flags, boolean bSet) { + if (bSet) { + this.flags |= flags; + } else { + this.flags &= ~flags; + } + } + + public void unsetFlags(int flags) { + setFlags(flags, false); + } + + public boolean isStart() { + return ((this.flags & NEW_AREA) != 0); + } + + public boolean startsNewArea() { + return ((this.flags & NEW_AREA) != 0 && leadingSpace != null); + } + + public boolean isFirstArea() { + return ((this.flags & FIRST_AREA) != 0); + } + + public boolean isLastArea() { + return ((this.flags & LAST_AREA) != 0); + } + + public boolean suppressLeadingSpace() { + return ((this.flags & SUPPRESS_LEADING_SPACE) != 0); + } + + public void setLeadingSpace(SpaceSpecifier space) { + leadingSpace = space; + } + + public SpaceSpecifier getLeadingSpace() { + return leadingSpace; + } + + public boolean resolveLeadingSpace() { + return ((this.flags & RESOLVE_LEADING_SPACE) != 0); + } + + public void setTrailingSpace(SpaceSpecifier space) { + trailingSpace = space; + } + + public SpaceSpecifier getTrailingSpace() { + return trailingSpace; + } + + public void setStackLimit(MinOptMax limit) { + stackLimit = limit; + } + + public MinOptMax getStackLimit() { + return stackLimit; + } + + public void setRefIPD(int ipd) { + refIPD = ipd; + } + + public int getRefIPD() { + return refIPD; + } + + public void setHyphContext(HyphContext hyph) { + hyphContext = hyph; + } + + public HyphContext getHyphContext() { + return hyphContext; + } + + public boolean tryHyphenate() { + return ((this.flags & TRY_HYPHENATE) != 0); + } + + public void setSpaceAdjust(double adjust) { + dSpaceAdjust = adjust; + } + + public double getSpaceAdjust() { + return dSpaceAdjust; + } + + public void setIPDAdjust(double ipdA) { + ipdAdjust = ipdA; + } + + public double getIPDAdjust() { + return ipdAdjust; + } + + public void setLineHeight(int lh) { + iLineHeight = lh; + } + + public int getLineHeight() { + return iLineHeight; + } + + public void setBaseline(int bl) { + iBaseline = bl; + } + + public int getBaseline() { + return iBaseline; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java new file mode 100644 index 000000000..628c46847 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java @@ -0,0 +1,85 @@ +/* + * $Id: LayoutManager.java,v 1.18 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fo.FObj; + +/** + * The interface for all LayoutManagers. + */ +public interface LayoutManager { + + /** + * Set the FO object for this layout manager. + * For layout managers that are created without an FO + * this may not be called. + * + * @param obj the FO object for this layout manager + */ + void setFObj(FObj obj); + + /** + * Set the user agent. For resolving user agent values + * and getting logger. + * + * @param ua the user agent + */ + void setUserAgent(FOUserAgent ua); + + /** + * Get the user agent. + * + * @return the user agent + */ + FOUserAgent getUserAgent(); + +} diff --git a/src/java/org/apache/fop/layoutmgr/LayoutProcessor.java b/src/java/org/apache/fop/layoutmgr/LayoutProcessor.java new file mode 100644 index 000000000..603a89c6e --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LayoutProcessor.java @@ -0,0 +1,232 @@ +/* + * $Id: LayoutProcessor.java,v 1.2 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.flow.Marker; + +import org.apache.fop.area.Area; +import org.apache.fop.area.Resolveable; +import org.apache.fop.area.PageViewport; + +import java.util.Map; + +/** + * The interface for all LayoutProcessors. + * This interface is used by the layout implementation to + * do the layout and add the areas. + */ +public interface LayoutProcessor extends LayoutManager { + + /** + * Set the parent layout manager. + * The parent layout manager is required for adding areas. + * + * @param lm the parent layout manager + */ + void setParent(LayoutProcessor lm); + + /** + * Initialise this layout manager. + */ + void init(); + + /** + * Generates inline areas. + * This is used to check if the layout manager generates inline + * areas. + * + * @return true if the layout manager generates inline areas + */ + boolean generatesInlineAreas(); + + /** + * Return true if the next area which would be generated by this + * LayoutManager could start a new line (or flow for block-level FO). + * + * @param lc the layout context + * @return true if can break before + */ + boolean canBreakBefore(LayoutContext lc); + + /** + * Generate and return the next break possibility. + * + * @param context The layout context contains information about pending + * space specifiers from ancestor areas or previous areas, reference + * area inline-progression-dimension and various other layout-related + * information. + * @return the next break position + */ + BreakPoss getNextBreakPoss(LayoutContext context); + + /** + * Reset to the position. + * + * @param position + */ + void resetPosition(Position position); + + /** + * Get the word chars between two positions and + * append to the string buffer. The positions could + * span multiple layout managers. + * + * @param sbChars the string buffer to append the word chars + * @param bp1 the start position + * @param bp2 the end position + */ + void getWordChars(StringBuffer sbChars, Position bp1, + Position bp2); + + /** + * Return a value indicating whether this LayoutManager has laid out + * all its content (or generated BreakPossibilities for all content.) + * + * @return true if this layout manager is finished + */ + boolean isFinished(); + + /** + * Set a flag indicating whether the LayoutManager has laid out all + * its content. This is generally called by the LM itself, but can + * be called by a parentLM when backtracking. + * + * @param isFinished the value to set the finished flag to + */ + void setFinished(boolean isFinished); + + /** + * Get the parent area for an area. + * This should get the parent depending on the class of the + * area passed in. + * + * @param childArea the child area to get the parent for + * @return the parent Area + */ + Area getParentArea(Area childArea); + + /** + * Add the area as a child of the current area. + * This is called by child layout managers to add their + * areas as children of the current area. + * + * @param childArea the child area to add + */ + void addChild(Area childArea); + + /** + * Tell the layout manager to add all the child areas implied + * by Position objects which will be returned by the + * Iterator. + * + * @param posIter the position iterator + * @param context the context + */ + void addAreas(PositionIterator posIter, LayoutContext context); + + /** + * Get the string of the current page number. + * + * @return the string for the current page number + */ + String getCurrentPageNumber(); + + /** + * Resolve the id reference. + * This is called by an area looking for an id reference. + * If the id reference is not found then it should add a resolveable object. + * + * @param ref the id reference + * @return the page containing the id reference or null if not found + */ + PageViewport resolveRefID(String ref); + + /** + * Add an id to the page. + * @todo add the location of the area on the page + * + * @param id the id reference to add. + */ + void addIDToPage(String id); + + /** + * Add an unresolved area. + * The is used to add a resolveable object to the page for a given id. + * + * @param id the id reference this object needs for resolving + * @param res the resolveable object + */ + void addUnresolvedArea(String id, Resolveable res); + + /** + * Add the marker. + * A number of formatting objects may contain markers. This + * method is used to add those markers to the page. + * + * @param name the marker class name + * @param start true if the formatting object is starting false is finishing + * @param isfirst a flag for is first + */ + void addMarkerMap(Map marks, boolean start, boolean isfirst); + + /** + * Retrieve a marker. + * This method is used when retrieve a marker. + * + * @param name the class name of the marker + * @param pos the retrieve position + * @param boundary the boundary for retrieving the marker + * @return the layout manaager of the retrieved marker if any + */ + Marker retrieveMarker(String name, int pos, int boundary); + +} + diff --git a/src/java/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java b/src/java/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java new file mode 100644 index 000000000..86d212c50 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LeafNodeLayoutManager.java @@ -0,0 +1,287 @@ +/* + * $Id: LeafNodeLayoutManager.java,v 1.23 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.area.Area; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.fo.properties.VerticalAlign; + +/** + * Base LayoutManager for leaf-node FObj, ie: ones which have no children. + * These are all inline objects. Most of them cannot be split (Text is + * an exception to this rule.) + * This class can be extended to handle the creation and adding of the + * inline area. + */ +public class LeafNodeLayoutManager extends AbstractLayoutManager { + /** + * The inline area that this leafnode will add. + */ + protected InlineArea curArea = null; + private int alignment; + private int lead; + private MinOptMax ipd; + + /** + * Create a Leaf node layout mananger. + */ + public LeafNodeLayoutManager() { + } + + /** + * get the inline area. + * @param context the context used to create the area + * @return the current inline area for this layout manager + */ + public InlineArea get(LayoutContext context) { + return curArea; + } + + /** + * Check if this generates inline areas. + * @return true always since this is an inline area manager + */ + public boolean generatesInlineAreas() { + return true; + } + + /** + * Check if this inline area is resolved due to changes in + * page or ipd. + * Currently not used. + * @return true if the area is resolved when adding + */ + public boolean resolved() { + return false; + } + + /** + * Set the current inline area. + * @param ia the inline area to set for this layout manager + */ + public void setCurrentArea(InlineArea ia) { + curArea = ia; + } + + /** + * Set the alignment of the inline area. + * @param al the vertical alignment positioning + */ + public void setAlignment(int al) { + alignment = al; + } + + /** + * Set the lead for this inline area. + * The lead is the distance from the top of the object + * to the baseline. + * Currently not used. + * @param l the lead value + */ + public void setLead(int l) { + lead = l; + } + + /** + * This is a leaf-node, so this method is never called. + * @param childArea the childArea to add + */ + public void addChild(Area childArea) { + } + + /** + * This is a leaf-node, so this method is never called. + * @param childArea the childArea to get the parent for + * @return the parent area + */ + public Area getParentArea(Area childArea) { + return null; + } + + /** + * Get the next break position. + * Since this holds an inline area it will return a single + * break position. + * @param context the layout context for this inline area + * @return the break poisition for adding this inline area + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + curArea = get(context); + if (curArea == null) { + setFinished(true); + return null; + } + BreakPoss bp = new BreakPoss(new LeafPosition(this, 0), + BreakPoss.CAN_BREAK_AFTER + | BreakPoss.CAN_BREAK_BEFORE | BreakPoss.ISFIRST + | BreakPoss.ISLAST); + ipd = getAllocationIPD(context.getRefIPD()); + bp.setStackingSize(ipd); + bp.setNonStackingSize(new MinOptMax(curArea.getHeight())); + bp.setTrailingSpace(new SpaceSpecifier(false)); + + int bpd = curArea.getHeight(); + switch (alignment) { + case VerticalAlign.MIDDLE: + bp.setMiddle(bpd / 2 /* - fontLead/2 */); + bp.setLead(bpd / 2 /* + fontLead/2 */); + break; + case VerticalAlign.TOP: + bp.setTotal(bpd); + break; + case VerticalAlign.BOTTOM: + bp.setTotal(bpd); + break; + case VerticalAlign.BASELINE: + default: + bp.setLead(bpd); + break; + } + setFinished(true); + return bp; + } + + /** + * Get the allocation ipd of the inline area. + * This method may be overridden to handle percentage values. + * @param refIPD the ipd of the parent reference area + * @return the min/opt/max ipd of the inline area + */ + protected MinOptMax getAllocationIPD(int refIPD) { + return new MinOptMax(curArea.getIPD()); + } + + /** + * Reset the position. + * If the reset position is null then this inline area should be + * restarted. + * @param resetPos the position to reset. + */ + public void resetPosition(Position resetPos) { + // only reset if setting null, start again + if (resetPos == null) { + setFinished(false); + } + } + + /** + * Add the area for this layout manager. + * This adds the single inline area to the parent. + * @param posIter the position iterator + * @param context the layout context for adding the area + */ + public void addAreas(PositionIterator posIter, LayoutContext context) { + parentLM.addChild(curArea); + + addID(); + + offsetArea(context); + widthAdjustArea(context); + + while (posIter.hasNext()) { + posIter.next(); + } + } + + /** + * Offset this area. + * Offset the inline area in the bpd direction when adding the + * inline area. + * This is used for vertical alignment. + * Subclasses should override this if necessary. + * @param context the layout context used for adding the area + */ + protected void offsetArea(LayoutContext context) { + int bpd = curArea.getHeight(); + switch (alignment) { + case VerticalAlign.MIDDLE: + curArea.setOffset(context.getBaseline() - bpd / 2 /* - fontLead/2 */); + break; + case VerticalAlign.TOP: + //curArea.setOffset(0); + break; + case VerticalAlign.BOTTOM: + curArea.setOffset(context.getLineHeight() - bpd); + break; + case VerticalAlign.BASELINE: + default: + curArea.setOffset(context.getBaseline() - bpd); + break; + } + } + + /** + * Adjust the width of the area when adding. + * This uses the min/opt/max values to adjust the with + * of the inline area by a percentage. + * @param context the layout context for adding this area + */ + protected void widthAdjustArea(LayoutContext context) { + double dAdjust = context.getIPDAdjust(); + int width = ipd.opt; + if (dAdjust < 0) { + width = (int)(width + dAdjust * (ipd.opt - ipd.min)); + } else if (dAdjust > 0) { + width = (int)(width + dAdjust * (ipd.max - ipd.opt)); + } + curArea.setWidth(width); + } + + /** + * Check if can break before this area. + * @param context the layout context to check for the break + * @return true if can break before this area in the context + */ + public boolean canBreakBefore(LayoutContext context) { + return true; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/LeafPosition.java b/src/java/org/apache/fop/layoutmgr/LeafPosition.java new file mode 100644 index 000000000..787b9bd85 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LeafPosition.java @@ -0,0 +1,66 @@ +/* + * $Id: LeafPosition.java,v 1.6 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +public class LeafPosition extends Position { + + private int iLeafPos; + + public LeafPosition(LayoutProcessor lm, int pos) { + super(lm); + iLeafPos = pos; + } + + public int getLeafPos() { + return iLeafPos; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java new file mode 100644 index 000000000..9d9a02e9c --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/LineLayoutManager.java @@ -0,0 +1,673 @@ +/* + * $Id: LineLayoutManager.java,v 1.24 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layout.MarginProps; +import org.apache.fop.layout.HyphenationProps; +import org.apache.fop.layout.hyphenation.Hyphenation; +import org.apache.fop.layout.hyphenation.Hyphenator; +import org.apache.fop.traits.BlockProps; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.Resolveable; +import org.apache.fop.fo.properties.TextAlign; + +import java.util.ListIterator; +import java.util.Iterator; +import java.util.List; +import java.util.ArrayList; + +/** + * LayoutManager for lines. It builds one or more lines containing + * inline areas generated by its sub layout managers. + * A break is found for each line which may contain one of more + * breaks from the child layout managers. + * Once a break is found then it is return for the parent layout + * manager to handle. + * When the areas are being added to the page this manager + * creates a line area to contain the inline areas added by the + * child layout managers. + */ +public class LineLayoutManager extends InlineStackingLayoutManager { + + /** + * Private class to store information about inline breaks. + * Each value holds the start and end indexes into a List of + * inline break positions. + */ + private static class LineBreakPosition extends LeafPosition { + // int iPos; + double dAdjust; // Percentage to adjust (stretch or shrink) + double ipdAdjust; // Percentage to adjust (stretch or shrink) + int startIndent; + int lineHeight; + int baseline; + + LineBreakPosition(LayoutProcessor lm, int iBreakIndex, + double ipdA, double adjust, int ind, int lh, int bl) { + super(lm, iBreakIndex); + // iPos = iBreakIndex; + ipdAdjust = ipdA; + dAdjust = adjust; + startIndent = ind; + lineHeight = lh; + baseline = bl; + } + } + + + /** Break positions returned by inline content. */ + private List vecInlineBreaks = new ArrayList(); + + private BreakPoss prevBP = null; // Last confirmed break position + private int bTextAlignment = TextAlign.JUSTIFY; + private int iTextIndent = 0; + private int iIndents = 0; + private HyphenationProps hyphProps; + + private int lineHeight; + private int lead; + private int follow; + + // inline start pos when adding areas + private int iStartPos = 0; + + /** + * Create a new Line Layout Manager. + * This is used by the block layout manager to create + * line managers for handling inline areas flowing into line areas. + * + * @param lh the default line height + * @param l the default lead, from top to baseline + * @param f the default follow, from baseline to bottom + */ + public LineLayoutManager(int lh, int l, int f) { + lineHeight = lh; + lead = l; + follow = f; + init(); // Normally done when started by parent! + } + + /** + * Initialize the properties for this layout manager. + * The properties are from the block area. + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + MarginProps marginProps = propMgr.getMarginProps(); + iIndents = marginProps.startIndent + marginProps.endIndent; + BlockProps blockProps = propMgr.getBlockProps(); + bTextAlignment = blockProps.textAlign; + iTextIndent = blockProps.firstIndent; + hyphProps = propMgr.getHyphenationProps(); + } + + /** + * Call child layout managers to generate content. + * This gets the next break which is a full line. + * + * @param context the layout context for finding breaks + * @return the next break position + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + // Get a break from currently active child LM + // Set up constraints for inline level managers + + LayoutProcessor curLM ; // currently active LM + BreakPoss prev = null; + BreakPoss bp = null; // proposed BreakPoss + + ArrayList vecPossEnd = new ArrayList(); + + // IPD remaining in line + MinOptMax availIPD = context.getStackLimit(); + + // QUESTION: maybe LayoutContext holds the Properties which + // come from block-level? + + LayoutContext inlineLC = new LayoutContext(context); + + clearPrevIPD(); + int iPrevLineEnd = vecInlineBreaks.size(); + + prevBP = null; + + while ((curLM = getChildLM()) != null) { + // INITIALIZE LAYOUT CONTEXT FOR CALL TO CHILD LM + // First break for the child LM in each of its areas + boolean bFirstBPforLM = (vecInlineBreaks.isEmpty() + || (((BreakPoss) vecInlineBreaks.get(vecInlineBreaks.size() - 1)). + getLayoutManager() != curLM)); + + // Need previous breakpoint! ATTENTION when backing up for hyphenation! + prev = (vecInlineBreaks.isEmpty()) + ? null + : (BreakPoss) vecInlineBreaks.get(vecInlineBreaks.size() - 1); + initChildLC(inlineLC, prev, + (vecInlineBreaks.size() == iPrevLineEnd), + bFirstBPforLM, new SpaceSpecifier(true)); + + + /* If first BP in this line but line is not first in this + * LM and previous line end decision was not forced (LINEFEED), + * then set the SUPPRESS_LEADING_SPACE flag. + */ + inlineLC.setFlags(LayoutContext.SUPPRESS_LEADING_SPACE, + (vecInlineBreaks.size() == iPrevLineEnd + && !vecInlineBreaks.isEmpty() + && ((BreakPoss) vecInlineBreaks.get(vecInlineBreaks.size() - 1)). + isForcedBreak() == false)); + + // GET NEXT POSSIBLE BREAK FROM CHILD LM + // prevBP = bp; + if ((bp = curLM.getNextBreakPoss(inlineLC)) != null) { + // Add any space before and previous content dimension + MinOptMax prevIPD = updatePrevIPD(bp, prev, + (vecInlineBreaks.size() == iPrevLineEnd), + inlineLC.isFirstArea()); + MinOptMax bpDim = + MinOptMax.add(bp.getStackingSize(), prevIPD); + + // check if this bp fits in line + boolean bBreakOK = couldEndLine(bp); + if (bBreakOK) { + /* Add any non-conditional trailing space, assuming we + * end the line here. If we can't break here, we just + * check if the content fits. + */ + bpDim.add(bp.resolveTrailingSpace(true)); + } + // TODO: stop if linebreak is forced (NEWLINE) + // PROBLEM: interaction with wrap which can be set + // at lower levels! + // System.err.println("BPdim=" + bpDim.opt); + + // Check if proposed area would fit in line + if (bpDim.min > availIPD.max) { + // See if we have already found a potential break + //if (vecPossEnd.size() > 0) break; + + // This break position doesn't fit + // TODO: If we are in nowrap, we use it as is! + if (bTextAlignment == TextAlign.JUSTIFY || prevBP == null) { + // If we are already in a hyphenation loop, then stop. + + if (inlineLC.tryHyphenate()) { + break; + } + // Otherwise, prepare to try hyphenation + if (!bBreakOK) { + // Make sure we collect the entire word! + vecInlineBreaks.add(bp); + continue; + } + + inlineLC.setHyphContext( + getHyphenContext(prevBP, bp)); + if (inlineLC.getHyphContext() == null) { + break; + } + inlineLC.setFlags(LayoutContext.TRY_HYPHENATE, + true); + // Reset to previous acceptable break + reset(); + } else { + /* If we are not in justified text, we can end the line at + * prevBP. + */ + break; + } + } else { + // Add the BP to the list whether or not we can break + vecInlineBreaks.add(bp); + // Handle end of this LM's areas + if (bBreakOK) { + prevBP = bp; // Save reference to this BP + if (bp.isForcedBreak()) { + break; + } + if (bpDim.max >= availIPD.min) { + /* This is a possible line BP (line could be filled) + * bpDim.max >= availIPD.min + * Keep this as a possible break, depending on + * "cost". We will choose lowest cost. + * Cost depends on stretch + * (ie, bpDim.opt closes to availIPD.opt), keeps + * and hyphenation. + */ + vecPossEnd.add(new BreakCost(bp, + Math.abs(availIPD.opt - bpDim.opt))); + } + // Otherwise it's short + } else { + /* Can't end line here. */ + } + } // end of bpDim.min <= availIPD.max + // end of getNextBreakPoss!=null on current child LM + } else { + /* The child LM can return a null BreakPoss if it has + * nothing (more) to layout. This can happen when backing + * up. Just try the next child LM. + */ + } + if (inlineLC.tryHyphenate() + && !inlineLC.getHyphContext().hasMoreHyphPoints()) { + break; + } + } // end of while on child LM + if ((curLM = getChildLM()) == null) { + // No more content to layout! + setFinished(true); + } + + if (bp == null) { + return null; + } + if (prevBP == null) { + prevBP = bp; + } + + // Choose the best break + if (!bp.isForcedBreak() && vecPossEnd.size() > 0) { + prevBP = getBestBP(vecPossEnd); + } + // Backup child LM if necessary + if (bp != prevBP && !bp.couldEndLine()) { + reset(); + } + + // Don't justify last line in the sequence or if forced line-end + int talign = bTextAlignment; + if ((bTextAlignment == TextAlign.JUSTIFY + && (prevBP.isForcedBreak() + || isFinished()))) { + talign = TextAlign.START; + } + return makeLineBreak(iPrevLineEnd, availIPD, talign); + } + + private void reset() { + while (vecInlineBreaks.get(vecInlineBreaks.size() - 1) != prevBP) { + vecInlineBreaks.remove(vecInlineBreaks.size() - 1); + } + reset(prevBP.getPosition()); + } + + protected boolean couldEndLine(BreakPoss bp) { + if (bp.canBreakAfter()) { + return true; // no keep, ends on break char + } else if (bp.isSuppressible()) { + // NOTE: except at end of content for this LM!! + // Never break after only space chars or any other sequence + // of areas which would be suppressed at the end of the line. + return false; + } else { + // See if could break before next area + // TODO: do we need to set anything on the layout context? + LayoutContext lc = new LayoutContext(0); + LayoutProcessor nextLM = getChildLM(); + return (nextLM == null || nextLM.canBreakBefore(lc)); + } + } + + private BreakPoss getBestBP(ArrayList vecPossEnd) { + if (vecPossEnd.size() == 1) { + return ((BreakCost) vecPossEnd.get(0)).getBP(); + } + // Choose the best break (use a sort on cost!) + Iterator iter = vecPossEnd.iterator(); + int minCost = Integer.MAX_VALUE; + BreakPoss bestBP = null; + while (iter.hasNext()) { + BreakCost bc = (BreakCost) iter.next(); + if (bc.getCost() < minCost) { + minCost = bc.getCost(); + bestBP = bc.getBP(); + } + } + return bestBP; + } + + /** Line area is always considered to act as a fence. */ + protected boolean hasLeadingFence(boolean bNotFirst) { + return true; + } + + /** Line area is always considered to act as a fence. */ + protected boolean hasTrailingFence(boolean bNotLast) { + return true; + } + + private HyphContext getHyphenContext(BreakPoss prev, + BreakPoss newBP) { + // Get a "word" to hyphenate by getting characters from all + // pending break poss which are in vecInlineBreaks, starting + // with the position just AFTER prev.getPosition() + + vecInlineBreaks.add(newBP); + ListIterator bpIter = + vecInlineBreaks.listIterator(vecInlineBreaks.size()); + while (bpIter.hasPrevious() && bpIter.previous() != prev) { + } + if (bpIter.next() != prev) { + getLogger().error("findHyphenPoss: problem!"); + return null; + } + StringBuffer sbChars = new StringBuffer(30); + while (bpIter.hasNext()) { + BreakPoss bp = (BreakPoss) bpIter.next(); + if (bp.getLayoutManager() == prev.getLayoutManager()) { + bp.getLayoutManager().getWordChars(sbChars, + prev.getPosition(), bp.getPosition()); + } else { + bp.getLayoutManager().getWordChars(sbChars, null, + bp.getPosition()); + } + prev = bp; + } + vecInlineBreaks.remove(vecInlineBreaks.size() - 1); // remove last + getLogger().debug("Word to hyphenate: " + sbChars.toString()); + + // Now find all hyphenation points in this word (get in an array of offsets) + // hyphProps are from the block level?. Note that according to the spec, + // they also "apply to" fo:character. I don't know what that means, since + // if we change language in the middle of a "word", the effect would seem + // quite strange! Or perhaps in that case, we say that it's several words. + // We probably should bring the hyphenation props up from the actual + // TextLM which generate the hyphenation buffer, since these properties + // inherit and could be specified on an inline or wrapper below the block + // level. + Hyphenation hyph = Hyphenator.hyphenate(hyphProps.language, + hyphProps.country, sbChars.toString(), + hyphProps.hyphenationRemainCharacterCount, + hyphProps.hyphenationPushCharacterCount); + // They hyph structure contains the information we need + // Now start from prev: reset to that position, ask that LM to get + // a Position for the first hyphenation offset. If the offset isn't in + // its characters, it returns null, but must tell how many chars it had. + // Keep looking at currentBP using next hyphenation point until the + // returned size is greater than the available size or no more hyphenation + // points remain. Choose the best break. + if (hyph != null) { + return new HyphContext(hyph.getHyphenationPoints()); + } else { + return null; + } + } + + /** + * Make a line break for returning as the next break. + * This makes the line break and calculates the height and + * ipd adjustment factors. + * + * @param prevLineEnd previous line break index + * @param target the target ipd value + * @param textalign the text align in operation for this line + * @return the line break position + */ + private BreakPoss makeLineBreak(int prevLineEnd, MinOptMax target, + int textalign) { + // make a new BP + // Store information needed to make areas in the LineBreakPosition! + + // lead to baseline is + // max of: baseline fixed alignment and middle/2 + // after baseline is + // max: top height-lead, middle/2 and bottom height-lead + int halfLeading = (lineHeight - lead - follow) / 2; + // height before baseline + int lineLead = lead + halfLeading; + // maximum size of top and bottom alignment + int maxtb = follow + halfLeading; + // max size of middle alignment below baseline + int middlefollow = maxtb; + + // calculate actual ipd + MinOptMax actual = new MinOptMax(); + BreakPoss lastBP = null; + LayoutManager lastLM = null; + for (Iterator iter = vecInlineBreaks.listIterator(prevLineEnd); + iter.hasNext();) { + BreakPoss bp = (BreakPoss)iter.next(); + if (bp.getLead() > lineLead) { + lineLead = bp.getLead(); + } + if (bp.getTotal() > maxtb) { + maxtb = bp.getTotal(); + } + if (bp.getMiddle() > middlefollow) { + middlefollow = bp.getMiddle(); + } + + // the stacking size of textLM accumulate for each break + // so the ipd is only added at the end of each LM + if (bp.getLayoutManager() != lastLM) { + if (lastLM != null) { + actual.add(lastBP.getStackingSize()); + } + lastLM = bp.getLayoutManager(); + } + lastBP = bp; + } + if (lastBP != null) { + // add final ipd + actual.add(lastBP.getStackingSize()); + // ATTENTION: make sure this hasn't gotten start space for next + // LM added onto it! + actual.add(lastBP.resolveTrailingSpace(true)); + } + + if (maxtb - lineLead > middlefollow) { + middlefollow = maxtb - lineLead; + } + + // in 7.21.4 the spec suggests that the leader and other + // similar min/opt/max areas should be adjusted before + // adjusting word spacing + + // Calculate stretch or shrink factor + double ipdAdjust = 0; + int targetWith = target.opt; + int realWidth = actual.opt; + if (actual.opt > targetWith) { + if (actual.opt - targetWith < (actual.opt - actual.min)) { + ipdAdjust = -(actual.opt - targetWith) + / (float)(actual.opt - actual.min); + realWidth = targetWith; + } else { + ipdAdjust = -1; + realWidth = actual.max; + } + } else { + if (targetWith - actual.opt < actual.max - actual.opt) { + ipdAdjust = (targetWith - actual.opt) + / (float)(actual.max - actual.opt); + realWidth = targetWith; + } else { + ipdAdjust = 1; + realWidth = actual.min; + } + } + + // if justifying then set the space adjustment + // after the normal ipd adjustment + double dAdjust = 0.0; + int indent = 0; + switch (textalign) { + case TextAlign.JUSTIFY: + if (realWidth != 0) { + dAdjust = (targetWith - realWidth) / realWidth; + } + break; + case TextAlign.START: + //indent = 0; + break; + case TextAlign.CENTER: + indent = (targetWith - realWidth) / 2; + break; + case TextAlign.END: + indent = targetWith - realWidth; + break; + } + + LineBreakPosition lbp; + lbp = new LineBreakPosition(this, + vecInlineBreaks.size() - 1, + ipdAdjust, dAdjust, indent, + lineLead + middlefollow, lineLead); + BreakPoss curLineBP = new BreakPoss(lbp); + + curLineBP.setFlag(BreakPoss.ISLAST, isFinished()); + curLineBP.setStackingSize(new MinOptMax(lineLead + middlefollow)); + return curLineBP; + } + + /** + * Reset the positions to the given position. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + iStartPos = 0; + reset(null); + vecInlineBreaks.clear(); + prevBP = null; + } else { + prevBP = (BreakPoss)vecInlineBreaks.get(((LineBreakPosition)resetPos).getLeafPos()); + while (vecInlineBreaks.get(vecInlineBreaks.size() - 1) != prevBP) { + vecInlineBreaks.remove(vecInlineBreaks.size() - 1); + } + reset(prevBP.getPosition()); + } + } + + /** + * Add the areas with the break points. + * + * @param parentIter the iterator of break positions + * @param context the context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext context) { + addAreas(parentIter, 0.0); + + //vecInlineBreaks.clear(); + prevBP = null; + } + + // Generate and add areas to parent area + // Set size etc + // dSpaceAdjust should reference extra space in the BPD + /** + * Add the areas with the associated space adjustment. + * + * @param parentIter the iterator of breaks positions + * @param dSpaceAdjust the space adjustment + */ + public void addAreas(PositionIterator parentIter, double dSpaceAdjust) { + LayoutProcessor childLM; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LineBreakPosition lbp = (LineBreakPosition) parentIter.next(); + LineArea lineArea = new LineArea(); + lineArea.setStartIndent(lbp.startIndent); + lineArea.setHeight(lbp.lineHeight); + lc.setBaseline(lbp.baseline); + lc.setLineHeight(lbp.lineHeight); + setCurrentArea(lineArea); + // Add the inline areas to lineArea + PositionIterator inlinePosIter = + new BreakPossPosIter(vecInlineBreaks, iStartPos, + lbp.getLeafPos() + 1); + iStartPos = lbp.getLeafPos() + 1; + lc.setSpaceAdjust(lbp.dAdjust); + lc.setIPDAdjust(lbp.ipdAdjust); + lc.setLeadingSpace(new SpaceSpecifier(true)); + lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true); + setChildContext(lc); + while ((childLM = inlinePosIter.getNextChildLM()) != null) { + childLM.addAreas(inlinePosIter, lc); + lc.setLeadingSpace(lc.getTrailingSpace()); + lc.setTrailingSpace(new SpaceSpecifier(false)); + } + // when can this be null? + if (lc.getTrailingSpace() != null) { + addSpace(lineArea, lc.getTrailingSpace().resolve(true), + lc.getSpaceAdjust()); + } + parentLM.addChild(lineArea); + } + setCurrentArea(null); // ?? necessary + } + + /** + * Add an unresolved area. + * If a child layout manager needs to add an unresolved area + * for page reference or linking then this intercepts it for + * line area handling. + * A line area may need to have the inline areas adjusted + * to properly fill the line area. This adds a resolver that + * resolves the inline area and can do the necessary + * adjustments to the line and inline areas. + * + * @param id the id reference of the resolveable + * @param res the resolveable object + */ + public void addUnresolvedArea(String id, Resolveable res) { + // create a resolveable class that handles ipd + // adjustment for the current line + + parentLM.addUnresolvedArea(id, res); + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/MinOptMax.java b/src/java/org/apache/fop/layoutmgr/MinOptMax.java new file mode 100644 index 000000000..2360e2cda --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/MinOptMax.java @@ -0,0 +1,161 @@ +/* + * $Id: MinOptMax.java,v 1.3 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +/** + * This class holds the resolved (as mpoints) form of a LengthRange or + * Space type Property value. + * MinOptMax values are used during layout calculations. The instance + * variables are package visible. + */ +public class MinOptMax implements java.io.Serializable, Cloneable { + + /** Publicly visible min(imum), opt(imum) and max(imum) values.*/ + public int min; + public int opt; + public int max; + + /** + * New min/opt/max with zero values. + */ + public MinOptMax() { + this(0); + } + + /** + * New min/opt/max with one fixed value. + * + * @param val the value for min, opt and max + */ + public MinOptMax(int val) { + this(val, val, val); + } + + /** + * New min/opt/max with the three values. + * + * @param min the minimum value + * @param opt the optimum value + * @param max the maximum value + */ + public MinOptMax(int min, int opt, int max) { + this.min = min; + this.opt = opt; + this.max = max; + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException ex) { + // SHOULD NEVER OCCUR - all members are primitive types! + return null; + } + } + + /** + * Subtracts one MinOptMax instance from another returning a new one. + * @param op1 first instance to subtract from + * @param op2 second instance + * @return MinOptMax new instance + */ + public static MinOptMax subtract(MinOptMax op1, MinOptMax op2) { + return new MinOptMax(op1.min - op2.max, op1.opt - op2.opt, + op1.max - op2.min); + } + + /** + * Adds one MinOptMax instance to another returning a new one. + * @param op1 first instance + * @param op2 second instance + * @return MinOptMax new instance + */ + public static MinOptMax add(MinOptMax op1, MinOptMax op2) { + return new MinOptMax(op1.min + op2.min, op1.opt + op2.opt, + op1.max + op2.max); + } + + /** + * Multiplies a MinOptMax instance with a factor returning a new instance. + * @param op1 MinOptMax instance + * @param mult multiplier + * @return MinOptMax new instance + */ + public static MinOptMax multiply(MinOptMax op1, double mult) { + return new MinOptMax((int)(op1.min * mult), + (int)(op1.opt * mult), (int)(op1.max * mult)); + } + + /** + * Adds another MinOptMax instance to this one. + * @param op the other instance + */ + public void add(MinOptMax op) { + min += op.min; + opt += op.opt; + max += op.max; + } + + /** + * Subtracts from this instance using another. + * @param op the other instance + */ + public void subtract(MinOptMax op) { + min -= op.max; + opt -= op.opt; + max -= op.min; + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/NonLeafPosition.java b/src/java/org/apache/fop/layoutmgr/NonLeafPosition.java new file mode 100644 index 000000000..a8c6c6029 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/NonLeafPosition.java @@ -0,0 +1,66 @@ +/* + * $Id: NonLeafPosition.java,v 1.6 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +public class NonLeafPosition extends Position { + + private Position subPos; + + public NonLeafPosition(LayoutProcessor lm, Position sub) { + super(lm); + subPos = sub; + } + + public Position getPosition() { + return subPos; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java new file mode 100644 index 000000000..e179edddf --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/PageLayoutManager.java @@ -0,0 +1,689 @@ +/* + * $Id: PageLayoutManager.java,v 1.33 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.AreaTree; +import org.apache.fop.area.AreaTreeModel; +import org.apache.fop.area.Area; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Flow; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.BodyRegion; +import org.apache.fop.area.MainReference; +import org.apache.fop.area.Span; +import org.apache.fop.area.BeforeFloat; +import org.apache.fop.area.Footnote; +import org.apache.fop.area.Resolveable; +import org.apache.fop.fo.flow.Marker; +import org.apache.fop.fo.flow.StaticContent; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.Region; +import org.apache.fop.fo.pagination.SimplePageMaster; +import org.apache.fop.fo.pagination.PageNumberGenerator; +import org.apache.fop.fo.properties.Constants; +import org.apache.fop.fo.properties.RetrieveBoundary; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * LayoutManager for a PageSequence and its flow. + * It manages all page-related layout. + */ +public class PageLayoutManager extends AbstractLayoutManager implements Runnable { + + private static class BlockBreakPosition extends LeafPosition { + protected BreakPoss breakps; + + protected BlockBreakPosition(LayoutProcessor lm, BreakPoss bp) { + super(lm, 0); + breakps = bp; + } + } + + private PageNumberGenerator pageNumberGenerator; + private int pageCount = 1; + private String pageNumberString; + private boolean isFirstPage = true; + + /** True if haven't yet laid out any pages.*/ + private boolean bFirstPage; + /** Current page being worked on. */ + private PageViewport curPage; + + /** Body region of the current page */ + private BodyRegion curBody; + + /** Current span being filled */ + private Span curSpan; + + /** Number of columns in current span area. */ + private int curSpanColumns; + + /** Current flow-reference-area (column) being filled. */ + private Flow curFlow; + + private int flowBPD = 0; + private int flowIPD = 0; + + /** Manager which handles a queue of all pages which are completely + * laid out and ready for rendering, except for resolution of ID + * references? + */ + private AreaTree areaTree; + private PageSequence pageSequence; + + /** + * This is the top level layout manager. + * It is created by the PageSequence FO. + * + * @param areaTree the area tree to add pages to + * @param pageseq the page sequence fo + */ + public PageLayoutManager(AreaTree areaTree, PageSequence pageseq) { + this.areaTree = areaTree; + pageSequence = pageseq; + } + + /** + * Set the page counting for this page sequence. + * This sets the initial page number and the page number formatter. + * + * @param pc the starting page number + * @param generator the page number generator + */ + public void setPageCounting(int pc, PageNumberGenerator generator) { + pageCount = pc; + pageNumberGenerator = generator; + pageNumberString = pageNumberGenerator.makeFormattedPageNumber(pageCount); + } + + /** + * Get the page count. + * Used to get the last page number for reference for + * the next page sequence. + * + * @return the page number + */ + public int getPageCount() { + return pageCount; + } + + /** + * The layout process is designed to be able to be run in a thread. + * In theory it can run at the same + * time as FO tree generation, once the layout-master-set has been read. + * We can arrange it so that the iterator over the fobj children waits + * until the next child is available. + * As it produces pages, it adds them to the AreaTree, where the + * rendering process can also run in a parallel thread. + */ + public void run() { + doLayout(); + flush(); + } + + /** + * Do the layout of this page sequence. + * This completes the layout of the page sequence + * which creates and adds all the pages to the area tree. + */ + protected void doLayout() { + + // this should be done another way + makeNewPage(false, false); + createBodyMainReferenceArea(); + createSpan(1); + flowIPD = curFlow.getIPD(); + + BreakPoss bp; + LayoutContext childLC = new LayoutContext(0); + while (!isFinished()) { + if ((bp = getNextBreakPoss(childLC)) != null) { + addAreas((BlockBreakPosition)bp.getPosition()); + // add static areas and resolve any new id areas + + // finish page and add to area tree + finishPage(); + pageCount++; + pageNumberString = pageNumberGenerator.makeFormattedPageNumber(pageCount); + } + } + pageCount--; + } + + /** + * Get the next break possibility. + * This finds the next break for a page which is always at the end + * of the page. + * + * @param context the layout context for finding breaks + * @return the break for the page + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + + LayoutProcessor curLM ; // currently active LM + + while ((curLM = getChildLM()) != null) { + BreakPoss bp = null; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(new MinOptMax(flowBPD)); + childLC.setRefIPD(flowIPD); + + if (!curLM.isFinished()) { + bp = curLM.getNextBreakPoss(childLC); + } + if (bp != null) { + return new BreakPoss( + new BlockBreakPosition(curLM, bp)); + } + } + setFinished(true); + return null; + } + + /** + * Get the current page number string. + * This returns the formatted string for the current page. + * + * @return the formatted page number string + */ + public String getCurrentPageNumber() { + return pageNumberString; + } + + /** + * Resolve a reference ID. + * This resolves a reference ID and returns the first PageViewport + * that contains the reference ID or null if reference not found. + * + * @param ref the reference ID to lookup + * @return the first page viewport that contains the reference + */ + public PageViewport resolveRefID(String ref) { + List list = areaTree.getIDReferences(ref); + if (list != null && list.size() > 0) { + return (PageViewport)list.get(0); + } + return null; + } + + /** + * Add the areas to the current page. + * Given the page break position this adds the areas to the current + * page. + * + * @param bbp the block break position + */ + public void addAreas(BlockBreakPosition bbp) { + List list = new ArrayList(); + list.add(bbp.breakps); + bbp.getLM().addAreas(new BreakPossPosIter(list, 0, + 1), null); + } + + /** + * Add an ID reference to the current page. + * When adding areas the area adds its ID reference. + * For the page layout manager it adds the id reference + * with the current page to the area tree. + * + * @param id the ID reference to add + */ + public void addIDToPage(String id) { + areaTree.addIDRef(id, curPage); + } + + /** + * Add an unresolved area to the layout manager. + * The Page layout manager handles the unresolved ID + * reference by adding to the current page and then adding + * the page as a resolveable to the area tree. + * This is so that the area tree can resolve the reference + * and the page can serialize the resolvers if required. + * + * @param id the ID reference to add + * @param res the resolveable object that needs resolving + */ + public void addUnresolvedArea(String id, Resolveable res) { + // add unresolved to tree + // adds to the page viewport so it can serialize + curPage.addUnresolvedID(id, res); + areaTree.addUnresolvedID(id, curPage); + } + + /** + * Add the marker to the page layout manager. + * + * @param name the marker class name + * @param lm the layout manager for the marker contents + * @param start true if starting marker area, false for ending + */ + public void addMarkerMap(Map marks, boolean start, boolean isfirst) { + //getLogger().debug("adding markers: " + marks + ":" + start); + // add markers to page on area tree + curPage.addMarkers(marks, start, isfirst); + } + + /** + * Retrieve a marker from this layout manager. + * If the boundary is page then it will only check the + * current page. For page-sequence and document it will + * lookup preceding pages from the area tree and try to find + * a marker. + * + * @param name the marker class name to lookup + * @param pos the position to locate the marker + * @param boundary the boundary for locating the marker + * @return the layout manager for the marker contents + */ + public Marker retrieveMarker(String name, int pos, int boundary) { + // get marker from the current markers on area tree + Marker mark = (Marker)curPage.getMarker(name, pos); + if (mark == null && boundary != RetrieveBoundary.PAGE) { + // go back over pages until mark found + // if document boundary then keep going + boolean doc = boundary == RetrieveBoundary.DOCUMENT; + AreaTreeModel atm = areaTree.getAreaTreeModel(); + int seq = atm.getPageSequenceCount(); + int page = atm.getPageCount(seq) - 1; + while (page >= 0) { + PageViewport pv = atm.getPage(seq, page); + mark = (Marker)curPage.getMarker(name, pos); + if (mark != null) { + return mark; + } + page--; + if (page == -1 && doc && seq > 0) { + seq--; + page = atm.getPageCount(seq) - 1; + } + } + } + + return mark; + } + + /** + * For now, only handle normal flow areas. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + if (childArea == null) { + return; + } + if (childArea.getAreaClass() == Area.CLASS_NORMAL) { + placeFlowRefArea(childArea); + } else { + ; // todo: all the others! + } + } + + /** + * Place a FlowReferenceArea into the current span. The FlowLM is + * responsible for making sure that it will actually fit in the + * current span area. In fact the area has already been added to the + * current span, so we are just checking to see if the span is "full", + * possibly moving to the next column or to the next page. + * + * @param area the area to place + */ + protected void placeFlowRefArea(Area area) { + // assert (curSpan != null); + // assert (area == curFlow); + // assert (curFlow == curSpan.getFlow(curSpan.getColumnCount()-1)); + // assert (area.getBPD().min < curSpan.getHeight()); + // Last column on this page is filled + // See if the flow is full. The Flow LM can add an area before + // it's full in the case of a break or a span. + // Also in the case of a float to be placed. In that case, there + // may be further material added later. + // The Flow LM sets the "finished" flag on the Flow Area if it has + // completely filled it. In this case, if on the last column + // end the page. + getParentArea(area); + // Alternatively the child LM indicates to parent that it's full? + //getLogger().debug("size: " + area.getAllocationBPD().max + + // ":" + curSpan.getMaxBPD().min); + /*if (area.getAllocationBPD().max >= curSpan.getMaxBPD().min) { + // Consider it filled + if (curSpan.getColumnCount() == curSpanColumns) { + finishPage(); + } else + curFlow = null; // Create new flow on next getParentArea() + }*/ + } + + protected void placeAbsoluteArea(Area area) { + } + + + protected void placeBeforeFloat(Area area) { + } + + protected void placeSideFloat(Area area) { + } + + protected void placeFootnote(Area area) { + // After doing this, reduce available space on the curSpan. + // This has to be propagated to the curFlow (FlowLM) so that + // it can adjust its limit for composition (or it just asks + // curSpan for BPD before doing the break?) + // If multi-column, we may have to balance to find more space + // for a float. When? + } + + private PageViewport makeNewPage(boolean bIsBlank, boolean bIsLast) { + finishPage(); + try { + curPage = pageSequence.createPage(pageCount, bIsBlank, isFirstPage, bIsLast); + isFirstPage = false; + } catch (FOPException fopex) { /* ???? */ + fopex.printStackTrace(); + } + + curPage.setPageNumber(getCurrentPageNumber()); + RegionViewport reg = curPage.getPage().getRegion( + RegionReference.BODY); + curBody = (BodyRegion) reg.getRegion(); + flowBPD = (int)reg.getViewArea().getHeight(); + return curPage; + } + + private void layoutStaticContent(Region region, int regionClass) { + if (region != null) { + StaticContent flow = pageSequence + .getStaticContent(region.getRegionName()); + if (flow != null) { + RegionViewport reg = curPage.getPage() + .getRegion(regionClass); + reg.getRegion().setIPD((int)reg.getViewArea().getWidth()); + if (reg == null) { + getLogger().error("no region viewport: shouldn't happen"); + } + StaticContentLayoutManager lm = flow.getLayoutManager(); + lm.setUserAgent(getUserAgent()); + lm.init(); + lm.setRegionReference(reg.getRegion()); + lm.setParent(this); + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(new MinOptMax((int)curPage.getViewArea().getHeight())); + childLC.setRefIPD((int)reg.getViewArea().getWidth()); + + while (!lm.isFinished()) { + BreakPoss bp = lm.getNextBreakPoss(childLC); + if (bp != null) { + List vecBreakPoss = new ArrayList(); + vecBreakPoss.add(bp); + lm.addAreas(new BreakPossPosIter(vecBreakPoss, 0, + vecBreakPoss.size()), null); + } else { + getLogger().error("bp==null cls=" + regionClass); + } + } + //lm.flush(); + lm.reset(null); + } + } + } + + private void finishPage() { + if (curPage != null) { + // Layout static content into the regions + // Need help from pageseq for this + SimplePageMaster spm = pageSequence.getCurrentSimplePageMaster(); + layoutStaticContent(spm.getRegion(Region.BEFORE), RegionReference.BEFORE); + layoutStaticContent(spm.getRegion(Region.AFTER), RegionReference.AFTER); + layoutStaticContent(spm.getRegion(Region.START), RegionReference.START); + layoutStaticContent(spm.getRegion(Region.END), RegionReference.END); + // Queue for ID resolution and rendering + areaTree.addPage(curPage); + curPage = null; + curBody = null; + curSpan = null; + curFlow = null; + } + } + + /** + * This is called from FlowLayoutManager when it needs to start + * a new flow container (while generating areas). + * + * @param childArea The area for which a container is needed. It must be + * some kind of block-level area. It must have area-class, break-before + * and span properties set. + * @return the parent area + */ + public Area getParentArea(Area childArea) { + int aclass = childArea.getAreaClass(); + if (aclass == Area.CLASS_NORMAL) { + // todo: how to get properties from the Area??? + // Need span, break + int breakVal = Constants.AUTO; // childArea.getBreakBefore(); + if (breakVal != Constants.AUTO) { + // We may be forced to make new page + handleBreak(breakVal); + } else if (curPage == null) { + makeNewPage(false, false); + } + // Now we should be on the right kind of page + boolean bNeedSpan = false; + int span = Constants.NONE; // childArea.getSpan() + int numCols = 1; + if (span == Constants.ALL) { + // Assume the number of columns is stored on the curBody object. + //numCols = curBody.getProperty(NUMBER_OF_COLUMNS); + } + if (curSpan == null) { + createBodyMainReferenceArea(); + bNeedSpan = true; + } else if (numCols != curSpanColumns) { + // todo: BALANCE EXISTING COLUMNS + if (curSpanColumns > 1) { + // balanceColumns(); + } + bNeedSpan = true; + } + if (bNeedSpan) { + // Make a new span and the first flow + createSpan(numCols); + } else if (curFlow == null) { + createFlow(); + } + return curFlow; + } else { + if (curPage == null) { + makeNewPage(false, false); + } + // Now handle different kinds of areas + if (aclass == Area.CLASS_BEFORE_FLOAT) { + BeforeFloat bf = curBody.getBeforeFloat(); + if (bf == null) { + bf = new BeforeFloat(); + curBody.setBeforeFloat(bf); + } + return bf; + } else if (aclass == Area.CLASS_FOOTNOTE) { + Footnote fn = curBody.getFootnote(); + if (fn == null) { + fn = new Footnote(); + curBody.setFootnote(fn); + } + return fn; + } + // todo!!! other area classes (side-float, absolute, fixed) + return null; + } + } + + /** + * Depending on the kind of break condition, make new column + * or page. May need to make an empty page if next page would + * not have the desired "handedness". + * + * @param breakVal the break value to handle + */ + protected void handleBreak(int breakVal) { + if (breakVal == Constants.COLUMN) { + if (curSpan != null + && curSpan.getColumnCount() != curSpanColumns) { + // Move to next column + createFlow(); + return; + } + // else need new page + breakVal = Constants.PAGE; + } + if (needEmptyPage(breakVal)) { + curPage = makeNewPage(true, false); + } + if (needNewPage(breakVal)) { + curPage = makeNewPage(false, false); + } + } + + /** + * If we have already started to layout content on a page, + * and there is a forced break, see if we need to generate + * an empty page. + * Note that if not all content is placed, we aren't sure whether + * it will flow onto another page or not, so we'd probably better + * block until the queue of layoutable stuff is empty! + */ + private boolean needEmptyPage(int breakValue) { + return false; + // if (breakValue == Constants.PAGE || curPage.isEmpty()) { + // // any page is OK or we already have an empty page + // return false; + // } + // else { + // /* IF we are on the kind of page we need, we'll need a new page. */ + // if (curPage.getPageNumber()%2 != 0) { + // // Current page is odd + // return (breakValue == Constants.ODD_PAGE); + // } + // else { + // return (breakValue == Constants.EVEN_PAGE); + // } + // } + } + + /** + * See if need to generate a new page for a forced break condition. + * todo: methods to see if the current page is empty and to get + * its number. + */ + private boolean needNewPage(int breakValue) { + return false; + //if (curPage.isEmpty()) { + //if (breakValue == Constants.PAGE) { + //return false; + //} + //else if (curPage.getPageNumber()%2 != 0) { + //// Current page is odd + //return (breakValue == Constants.EVEN_PAGE); + //} + //else { + //return (breakValue == Constants.ODD_PAGE); + //} + //} + //else { + // return true; + //} + } + + private void createBodyMainReferenceArea() { + curBody.setMainReference(new MainReference()); + } + + private Flow createFlow() { + curFlow = new Flow(); + curFlow.setIPD(curSpan.getIPD()); // adjust for columns + //curFlow.setBPD(100000); + // Set IPD and max BPD on the curFlow from curBody + curSpan.addFlow(curFlow); + return curFlow; + } + + private void createSpan(int numCols) { + // check number of columns (= all in Body or 1) + // If already have a span, get its size and position (as MinMaxOpt) + // This determines the position of the new span area + // Attention: space calculation between the span areas. + + //MinOptMax newpos ; + //if (curSpan != null) { + //newpos = curSpan.getPosition(BPD); + //newpos.add(curSpan.getDimension(BPD)); + //} + //else newpos = new MinOptMax(); + curSpan = new Span(numCols); + // get Width or Height as IPD for span + curSpan.setIPD((int) curPage.getPage().getRegion( + RegionReference.BODY).getViewArea().getWidth()); + + //curSpan.setPosition(BPD, newpos); + curBody.getMainReference().addSpan(curSpan); + createFlow(); + } + + // See finishPage... + protected void flush() { + finishPage(); + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/Position.java b/src/java/org/apache/fop/layoutmgr/Position.java new file mode 100644 index 000000000..84f95e4fe --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/Position.java @@ -0,0 +1,73 @@ +/* + * $Id: Position.java,v 1.6 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +public class Position { + + private LayoutProcessor layoutManager; + + public Position(LayoutProcessor lm) { + layoutManager = lm; + } + + public LayoutProcessor getLM() { + return layoutManager; + } + + /** + * Overridden by NonLeafPosition to return the Position of its + * child LM. + */ + public Position getPosition() { + return null; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/PositionIterator.java b/src/java/org/apache/fop/layoutmgr/PositionIterator.java new file mode 100644 index 000000000..d05aea5f0 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/PositionIterator.java @@ -0,0 +1,133 @@ +/* + * $Id: PositionIterator.java,v 1.11 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +public abstract class PositionIterator implements Iterator { + + private Iterator parentIter; + private Object nextObj; + private LayoutProcessor childLM; + private boolean bHasNext; + + PositionIterator(Iterator pIter) { + parentIter = pIter; + lookAhead(); + //checkNext(); + } + + public LayoutProcessor getNextChildLM() { + // Move to next "segment" of iterator, ie: new childLM + if (childLM == null && nextObj != null) { + childLM = getLM(nextObj); + bHasNext = true; + } + return childLM; + } + + protected abstract LayoutProcessor getLM(Object nextObj); + + protected abstract Position getPos(Object nextObj); + + private void lookAhead() { + if (parentIter.hasNext()) { + bHasNext = true; + nextObj = parentIter.next(); + } else { + endIter(); + } + } + + protected boolean checkNext() { + LayoutProcessor lm = getLM(nextObj); + if (childLM == null) { + childLM = lm; + } else if (childLM != lm) { + // End of this sub-sequence with same child LM + bHasNext = false; + childLM = null; + return false; + } + return true; + } + + protected void endIter() { + bHasNext = false; + nextObj = null; + childLM = null; + } + + public boolean hasNext() { + return (bHasNext && checkNext()); + } + + + public Object next() throws NoSuchElementException { + if (bHasNext) { + Object retObj = getPos(nextObj); + lookAhead(); + return retObj; + } else { + throw new NoSuchElementException("PosIter"); + } + } + + protected Object peekNext() { + return nextObj; + } + + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException("PositionIterator doesn't support remove"); + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/RetrieveMarkerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/RetrieveMarkerLayoutManager.java new file mode 100644 index 000000000..3d6ab5391 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/RetrieveMarkerLayoutManager.java @@ -0,0 +1,175 @@ +/* + * $Id: RetrieveMarkerLayoutManager.java,v 1.4 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.fop.area.Area; +import org.apache.fop.fo.flow.Marker; + +/** + * LayoutManager for a block FO. + */ +public class RetrieveMarkerLayoutManager extends AbstractLayoutManager { + private LayoutProcessor replaceLM = null; + private boolean loaded = false; + private String name; + private int position; + private int boundary; + + /** + * Create a new block container layout manager. + */ + public RetrieveMarkerLayoutManager(String n, int pos, int bound) { + name = n; + position = pos; + boundary = bound; + } + + public boolean generatesInlineAreas() { + loadLM(); + if (replaceLM == null) { + return true; + } + return replaceLM.generatesInlineAreas(); + } + + public BreakPoss getNextBreakPoss(LayoutContext context) { + loadLM(); + if (replaceLM == null) { + return null; + } + return replaceLM.getNextBreakPoss(context); + } + + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + + loadLM(); + addID(); + replaceLM.addAreas(parentIter, layoutContext); + + } + + public boolean isFinished() { + loadLM(); + if (replaceLM == null) { + return true; + } + return replaceLM.isFinished(); + } + + public void setFinished(boolean fin) { + if (replaceLM != null) { + replaceLM.setFinished(fin); + } + } + + protected void loadLM() { + if (loaded) { + return; + } + loaded = true; + if (replaceLM == null) { + List list = new ArrayList(); + Marker marker = retrieveMarker(name, position, boundary); + if (marker != null) { + marker.addLayoutManager(list); + if (list.size() > 0) { + replaceLM = (LayoutProcessor)list.get(0); + replaceLM.setParent(this); + replaceLM.init(); + getLogger().debug("retrieved: " + replaceLM + ":" + list.size()); + } else { + getLogger().debug("found no marker with name: " + name); + } + } + } + } + + /** + * Get the parent area for children of this block container. + * This returns the current block container area + * and creates it if required. + * + * @see org.apache.fop.layoutmgr.LayoutManager#getParentArea(Area) + */ + public Area getParentArea(Area childArea) { + return parentLM.getParentArea(childArea); + } + + /** + * Add the child to the block container. + * + * @see org.apache.fop.layoutmgr.LayoutManager#addChild(Area) + */ + public void addChild(Area childArea) { + parentLM.addChild(childArea); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#resetPosition(Position) + */ + public void resetPosition(Position resetPos) { + loadLM(); + if (resetPos == null) { + reset(null); + } + if (replaceLM != null) { + replaceLM.resetPosition(null); + } + loaded = false; + replaceLM = null; + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java b/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java new file mode 100644 index 000000000..a6a716f6a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/SpaceSpecifier.java @@ -0,0 +1,184 @@ +/* + * $Id: SpaceSpecifier.java,v 1.11 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.traits.SpaceVal; +import java.util.ArrayList; +import java.util.List; + +/** + * Accumulate a sequence of space-specifiers (XSL space type) on + * areas with a stacking constraint. Provide a way to resolve these into + * a single MinOptMax value. + */ +public class SpaceSpecifier implements Cloneable { + + + private boolean bStartsRefArea; + private boolean bHasForcing = false; + private List vecSpaceVals = new java.util.ArrayList(); + + + /** + * Creates a new SpaceSpecifier. + * @param bStarts true if it starts anew reference area + */ + public SpaceSpecifier(boolean bStarts) { + bStartsRefArea = bStarts; + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + SpaceSpecifier ss = (SpaceSpecifier) super.clone(); + // Clone the vector, but share the objects in it! + ss.vecSpaceVals = new ArrayList(); + ss.vecSpaceVals.addAll(this.vecSpaceVals); + return ss; + } catch (CloneNotSupportedException cnse) { + return null; + } + + } + + /** + * Clear all space specifiers + */ + public void clear() { + bHasForcing = false; + vecSpaceVals.clear(); + } + + /** + * Indicates whether any space-specifiers have been added. + * @return true if any space-specifiers have been added. + */ + public boolean hasSpaces() { + return (vecSpaceVals.size() > 0); + } + + /** + * Add a new space to the sequence. If this sequence starts a reference + * area, and the added space is conditional, and there are no + * non-conditional values in the sequence yet, then ignore it. Otherwise + * add it to the sequence. + */ + public void addSpace(SpaceVal moreSpace) { + if (!bStartsRefArea + || !moreSpace.isConditional() + || !vecSpaceVals.isEmpty()) { + if (moreSpace.isForcing()) { + if (bHasForcing == false) { + // Remove all other values (must all be non-forcing) + vecSpaceVals.clear(); + bHasForcing = true; + } + vecSpaceVals.add(moreSpace); + } else if (bHasForcing == false) { + // Don't bother adding all 0 space-specifier if not forcing + if (moreSpace.getSpace().min != 0 + || moreSpace.getSpace().opt != 0 + || moreSpace.getSpace().max != 0) { + vecSpaceVals.add(moreSpace); + } + } + } + } + + + /** + * Resolve the current sequence of space-specifiers, accounting for + * forcing values. + * @param bEndsReferenceArea True if the sequence should be resolved + * at the trailing edge of reference area. + * @return The resolved value as a min/opt/max triple. + */ + public MinOptMax resolve(boolean bEndsReferenceArea) { + int lastIndex = vecSpaceVals.size(); + if (bEndsReferenceArea) { + // Start from the end and count conditional specifiers + // Stop at first non-conditional + for (; lastIndex > 0; --lastIndex) { + SpaceVal sval = (SpaceVal) vecSpaceVals.get( + lastIndex - 1); + if (!sval.isConditional()) { + break; + } + } + } + MinOptMax resSpace = new MinOptMax(0); + int iMaxPrec = -1; + for (int index = 0; index < lastIndex; index++) { + SpaceVal sval = (SpaceVal) vecSpaceVals.get(index); + if (bHasForcing) { + resSpace.add(sval.getSpace()); + } else if (sval.getPrecedence() > iMaxPrec) { + iMaxPrec = sval.getPrecedence(); + resSpace = sval.getSpace(); + } else if (sval.getPrecedence() == iMaxPrec) { + if (sval.getSpace().opt > resSpace.opt) { + resSpace = sval.getSpace(); + } else if (sval.getSpace().opt == resSpace.opt) { + if (resSpace.min < sval.getSpace().min) { + resSpace.min = sval.getSpace().min; + } + if (resSpace.max > sval.getSpace().max) { + resSpace.max = sval.getSpace().max; + } + } + } + + } + return resSpace; + } +} diff --git a/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java new file mode 100644 index 000000000..4fc2b5c44 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/StaticContentLayoutManager.java @@ -0,0 +1,166 @@ +/* + * $Id: StaticContentLayoutManager.java,v 1.13 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * LayoutManager for an fo:flow object. + * Its parent LM is the PageLayoutManager. + * This LM is responsible for getting columns of the appropriate size + * and filling them with block-level areas generated by its children. + */ +public class StaticContentLayoutManager extends BlockStackingLayoutManager { + + private RegionReference region; + private List blockBreaks = new ArrayList(); + + /** + * Sets the region reference + * @param region region reference + */ + public void setRegionReference(RegionReference region) { + this.region = region; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#getNextBreakPoss(LayoutContext) + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + + // currently active LM + LayoutProcessor curLM; + + while ((curLM = getChildLM()) != null) { + // Make break positions and return page break + // Set up a LayoutContext + BreakPoss bp; + LayoutContext childLC = context; + if (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + blockBreaks.add(bp); + if (bp.isForcedBreak()) { + getLogger().error("Forced breaks are not allowed in " + + "static content - ignoring"); + return null; + } + } + } + } + setFinished(true); + if (blockBreaks.size() > 0) { + return new BreakPoss( + new LeafPosition(this, blockBreaks.size() - 1)); + } + return null; + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#addAreas(PositionIterator, LayoutContext) + */ + public void addAreas(PositionIterator parentIter, LayoutContext layoutContext) { + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(blockBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + blockBreaks.clear(); + flush(); + region = null; + } + + + /** + * Add child area to a the correct container, depending on its + * area class. A Flow can fill at most one area container of any class + * at any one time. The actual work is done by BlockStackingLM. + * @param childArea child area to add + */ + public void addChild(Area childArea) { + region.addBlock((Block)childArea); + } + + /** + * @see org.apache.fop.layoutmgr.LayoutProcessor#getParentArea(Area) + */ + public Area getParentArea(Area childArea) { + return region; + } + + /** + * Markers are not allowed in static areas so this reports an + * error and does nothing. + * + * @see org.apache.fop.layoutmgr.LayoutManager + */ + public void addMarker(Map marks, boolean start, boolean isfirst) { + // error markers not allowed in static + getLogger().error("Cannot add marker to static areas"); + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java new file mode 100644 index 000000000..e26000f04 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/TextLayoutManager.java @@ -0,0 +1,587 @@ +/* + * $Id: TextLayoutManager.java,v 1.21 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import java.util.ArrayList; + +import org.apache.fop.fo.TextInfo; +import org.apache.fop.traits.SpaceVal; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.InlineArea; +import org.apache.fop.area.inline.Word; +import org.apache.fop.area.inline.Space; +import org.apache.fop.util.CharUtilities; + +/** + * LayoutManager for text (a sequence of characters) which generates one + * or more inline areas. + */ +public class TextLayoutManager extends AbstractLayoutManager { + + /** + * Store information about each potential word 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 short iStartIndex; + private short iBreakIndex; + private short iWScount; + private MinOptMax ipdArea; + public AreaInfo(short iSIndex, short iBIndex, short iWS, + MinOptMax ipd) { + iStartIndex = iSIndex; + iBreakIndex = iBIndex; + iWScount = iWS; + ipdArea = ipd; + } + } + + + // Hold all possible breaks for the text in this LM's FO. + private ArrayList vecAreaInfo; + + /** Non-space characters on which we can end a line. */ + private static final String BREAK_CHARS = "-/" ; + + private char[] chars; + private TextInfo textInfo; + + private static final char NEWLINE = '\n'; + private static final char SPACE = '\u0020'; // Normal space + private static final char NBSPACE = '\u00A0'; // Non-breaking space + private static final char LINEBREAK = '\u2028'; + private static final char ZERO_WIDTH_SPACE = '\u200B'; + // byte order mark + private static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF'; + + /** Start index of first character in this parent Area */ + private short iAreaStart = 0; + /** Start index of next "word" */ + private short iNextStart = 0; + /** Size since last makeArea call, except for last break */ + private MinOptMax ipdTotal; + /** Size including last break possibility returned */ + // private MinOptMax nextIPD = new MinOptMax(0); + /** size of a space character (U+0020) glyph in current font */ + private int spaceCharIPD; + /** size of the hyphen character glyph in current font */ + private int hyphIPD; + /** 1/2 of word-spacing value */ + private SpaceVal halfWS; + /** Number of space characters after previous possible break position. */ + private int iNbSpacesPending; + + /** + * Create a Text layout manager. + * + * @param chars the characters + * @param textInfo the text information for doing layout + */ + public TextLayoutManager(char[] chars, TextInfo textInfo) { + this.chars = chars; + this.textInfo = textInfo; + this.vecAreaInfo = new java.util.ArrayList(); + + // With CID fonts, space isn't neccesary currentFontState.width(32) + spaceCharIPD = CharUtilities.getCharWidth(' ', textInfo.fs); + // Use hyphenationChar property + hyphIPD = CharUtilities.getCharWidth('-', textInfo.fs); + // Make half-space: on either side of a word-space) + SpaceVal ws = textInfo.wordSpacing; + halfWS = new SpaceVal(MinOptMax.multiply(ws.getSpace(), 0.5), + ws.isConditional(), ws.isForcing(), ws.getPrecedence()); + } + + /** + * Text always generates inline areas. + * + * @return true + */ + public boolean generatesInlineAreas() { + return true; + } + + /** + * Get the word characters between two positions. + * This is used when doing hyphenation or other word manipulations. + * + * @param sbChars the string buffer to put the chars into + * @param bp1 the start position + * @param bp2 the end position + */ + public void getWordChars(StringBuffer sbChars, Position bp1, + Position bp2) { + LeafPosition endPos = (LeafPosition) bp2; + AreaInfo ai = + (AreaInfo) vecAreaInfo.get(endPos.getLeafPos()); + // Skip all leading spaces for hyphenation + int i; + for (i = ai.iStartIndex; + i < ai.iBreakIndex && CharUtilities.isAnySpace(chars[i]) == true; + i++) { + //nop + } + sbChars.append(new String(chars, i, ai.iBreakIndex - i)); + } + + /** + * Return value indicating whether the next area to be generated could + * start a new line. This should only be called in the "START" condition + * if a previous inline BP couldn't end the line. + * Return true if the first character is a potential linebreak character. + * + * @param context the layout context for determining a break + * @return true if can break before this text + */ + public boolean canBreakBefore(LayoutContext context) { + char c = chars[iNextStart]; + return ((c == NEWLINE) + || (textInfo.bWrap && (CharUtilities.isSpace(c) + || BREAK_CHARS.indexOf(c) >= 0))); + } + + /** + * Reset position for returning next BreakPossibility. + * + * @param prevPos the position to reset to + */ + public void resetPosition(Position prevPos) { + if (prevPos != null) { + // ASSERT (prevPos.getLM() == this) + if (prevPos.getLM() != this) { + getLogger().error( + "TextLayoutManager.resetPosition: " + "LM mismatch!!!"); + } + LeafPosition tbp = (LeafPosition) prevPos; + AreaInfo ai = + (AreaInfo) vecAreaInfo.get(tbp.getLeafPos()); + if (ai.iBreakIndex != iNextStart) { + iNextStart = ai.iBreakIndex; + vecAreaInfo.ensureCapacity(tbp.getLeafPos() + 1); + // TODO: reset or recalculate total IPD = sum of all word IPD + // up to the break position + ipdTotal = ai.ipdArea; + setFinished(false); + } + } else { + // Reset to beginning! + vecAreaInfo.clear(); + iNextStart = 0; + setFinished(false); + } + } + + // TODO: see if we can use normal getNextBreakPoss for this with + // extra hyphenation information in LayoutContext + private boolean getHyphenIPD(HyphContext hc, MinOptMax hyphIPD) { + // Skip leading word-space before calculating count? + boolean bCanHyphenate = true; + int iStopIndex = iNextStart + hc.getNextHyphPoint(); + + if (chars.length < iStopIndex || textInfo.bCanHyphenate == false) { + iStopIndex = chars.length; + bCanHyphenate = false; + } + hc.updateOffset(iStopIndex - iNextStart); + + for (; iNextStart < iStopIndex; iNextStart++) { + char c = chars[iNextStart]; + hyphIPD.opt += CharUtilities.getCharWidth(c, textInfo.fs); + // letter-space? + } + // Need to include hyphen size too, but don't count it in the + // stored running total, since it would be double counted + // with later hyphenation points + return bCanHyphenate; + } + + /** + * Return the next break possibility that fits the constraints. + * @param context An object specifying the flags and input information + * concerning the context of the BreakPoss. + * @return BreakPoss An object containing information about the next + * legal break position or the end of the text run if no break + * was found. + *

Assumptions: white-space-treatment and + * linefeed-treatment processing + * are already done, so there are no TAB or RETURN characters remaining. + * white-space-collapse handling is also done + * (but perhaps this shouldn't be true!) + * There may be LINEFEED characters if they weren't converted + * into spaces. A LINEFEED always forces a break. + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + /* On first call in a new Line, the START_AREA + * flag in LC is set. + */ + + int iFlags = 0; + + if (context.startsNewArea()) { + /* This could be first call on this LM, or the first call + * in a new (possible) LineArea. + */ + ipdTotal = new MinOptMax(0); + iFlags |= BreakPoss.ISFIRST; + } + + + /* HANDLE SUPPRESSED LEADING SPACES + * See W3C XSL Rec. 7.16.3. + * Suppress characters whose "suppress-at-line-break" property = "suppress" + * This can only be set on an explicit fo:character object. The default + * behavior is that U+0020 is suppressed; all other character codes are + * retained. + */ + if (context.suppressLeadingSpace()) { + for (; iNextStart < chars.length + && chars[iNextStart] == SPACE; iNextStart++) { + } + // If now at end, nothing to compose here! + if (iNextStart >= chars.length) { + setFinished(true); + return null; // Or an "empty" BreakPoss? + } + } + + + /* Start of this "word", plus any non-suppressed leading space. + * Collapse any remaining word-space with leading space from + * ancestor FOs. + * Add up other leading space which is counted in the word IPD. + */ + + SpaceSpecifier pendingSpace = new SpaceSpecifier(false); + short iThisStart = iNextStart; // Index of first character counted + MinOptMax spaceIPD = new MinOptMax(0); // Extra IPD from word-spacing + // Sum of glyph IPD of all characters in a word, inc. leading space + int wordIPD = 0; + short iWScount = 0; // Count of word spaces + boolean bSawNonSuppressible = false; + + for (; iNextStart < chars.length; iNextStart++) { + char c = chars[iNextStart]; + if (CharUtilities.isAnySpace(c) == false) { + break; + } + if (c == SPACE || c == NBSPACE) { + ++iWScount; + // Counted as word-space + if (iNextStart == iThisStart + && (iFlags & BreakPoss.ISFIRST) != 0) { + // If possible, treat as normal inter-word space + if (context.getLeadingSpace().hasSpaces()) { + context.getLeadingSpace().addSpace(halfWS); + } else { + // Doesn't combine with any other leading spaces + // from ancestors + spaceIPD.add(halfWS.getSpace()); + } + } else { + pendingSpace.addSpace(halfWS); + spaceIPD.add(pendingSpace.resolve(false)); + } + wordIPD += spaceCharIPD; // Space glyph IPD + pendingSpace.clear(); + pendingSpace.addSpace(halfWS); + if (c == NBSPACE) { + bSawNonSuppressible = true; + } + } else { + // If we have letter-space, so we apply this to fixed- + // width spaces (which are not word-space) also? + bSawNonSuppressible = true; + spaceIPD.add(pendingSpace.resolve(false)); + pendingSpace.clear(); + wordIPD += CharUtilities.getCharWidth(c, textInfo.fs); + } + } + + if (iNextStart < chars.length) { + spaceIPD.add(pendingSpace.resolve(false)); + } else { + // This FO ended with spaces. Return the BP + if (!bSawNonSuppressible) { + iFlags |= BreakPoss.ALL_ARE_SUPPRESS_AT_LB; + } + return makeBreakPoss(iThisStart, spaceIPD, wordIPD, + context.getLeadingSpace(), pendingSpace, iFlags, + iWScount); + } + + if (context.tryHyphenate()) { + // Get the size of the next syallable + MinOptMax hyphIPD = new MinOptMax(0); + if (getHyphenIPD(context.getHyphContext(), hyphIPD)) { + iFlags |= (BreakPoss.CAN_BREAK_AFTER | BreakPoss.HYPHENATED); + } + wordIPD += hyphIPD.opt; + } else { + // Look for a legal line-break: breakable white-space and certain + // characters such as '-' which can serve as word breaks. + // Don't look for hyphenation points here though + for (; iNextStart < chars.length; iNextStart++) { + char c = chars[iNextStart]; + if ((c == NEWLINE) || // Include any breakable white-space as break char + // even if fixed width + (textInfo.bWrap && (CharUtilities.isSpace(c) + || BREAK_CHARS.indexOf(c) >= 0))) { + iFlags |= BreakPoss.CAN_BREAK_AFTER; + if (c != SPACE) { + iNextStart++; + if (c != NEWLINE) { + wordIPD += CharUtilities.getCharWidth(c, + textInfo.fs); + } else { + iFlags |= BreakPoss.FORCE; + } + } + // If all remaining characters would be suppressed at + // line-end, set a flag for parent LM. + int iLastChar; + for (iLastChar = iNextStart; + iLastChar < chars.length + && chars[iLastChar] == SPACE; iLastChar++) { + //nop + } + if (iLastChar == chars.length) { + iFlags |= BreakPoss.REST_ARE_SUPPRESS_AT_LB; + } + return makeBreakPoss(iThisStart, spaceIPD, wordIPD, + context.getLeadingSpace(), null, iFlags, + iWScount); + } + wordIPD += CharUtilities.getCharWidth(c, textInfo.fs); + // Note, if a normal non-breaking space, is it stretchable??? + // If so, keep a count of these embedded spaces. + } + } + return makeBreakPoss(iThisStart, spaceIPD, wordIPD, + context.getLeadingSpace(), null, iFlags, iWScount); + } + + private BreakPoss makeBreakPoss(short iWordStart, + MinOptMax spaceIPD, int wordDim, + SpaceSpecifier leadingSpace, SpaceSpecifier trailingSpace, + int flags, short iWScount) { + MinOptMax ipd = new MinOptMax(wordDim); + ipd.add(spaceIPD); + if (ipdTotal != null) { + ipd.add(ipdTotal); // sum of all words so far in line + } + // Note: break position now stores total size to here + + // Position is the index of the info for this word in the vector + vecAreaInfo.add( + new AreaInfo(iWordStart, iNextStart, iWScount, ipd)); + BreakPoss bp = new BreakPoss( + new LeafPosition(this, vecAreaInfo.size() - 1)); + ipdTotal = ipd; + if ((flags & BreakPoss.HYPHENATED) != 0) { + // Add the hyphen size, but don't change total IPD! + bp.setStackingSize( + MinOptMax.add(ipd, new MinOptMax(hyphIPD))); + } else { + bp.setStackingSize(ipd); + } + // TODO: make this correct (see Keiron's vertical alignment code) + bp.setNonStackingSize(new MinOptMax(textInfo.lineHeight)); + + /* Set max ascender and descender (offset from baseline), + * used for calculating the bpd of the line area containing + * this text. + */ + //bp.setDescender(textInfo.fs.getDescender()); + //bp.setAscender(textInfo.fs.getAscender()); + if (iNextStart == chars.length) { + flags |= BreakPoss.ISLAST; + setFinished(true); + } + bp.setFlag(flags); + if (trailingSpace != null) { + bp.setTrailingSpace(trailingSpace); + } else { + bp.setTrailingSpace(new SpaceSpecifier(false)); + } + if (leadingSpace != null) { + bp.setLeadingSpace(leadingSpace); + } else { + bp.setLeadingSpace(new SpaceSpecifier(false)); + } + return bp; + } + + + /** + * Generate and add areas to parent area. + * This can either generate an area for each "word" and each space, or + * an area containing all text with a parameter controlling the size of + * the word space. The latter is most efficient for PDF generation. + * Set size of each area. + * @param posIter Iterator over Position information returned + * by this LayoutManager. + * @param context LayoutContext for adjustments + */ + public void addAreas(PositionIterator posIter, LayoutContext context) { + // Add word areas + AreaInfo ai = null ; + int iStart = -1; + int iWScount = 0; + + /* On first area created, add any leading space. + * Calculate word-space stretch value. + */ + while (posIter.hasNext()) { + LeafPosition tbpNext = (LeafPosition) posIter.next(); + ai = (AreaInfo) vecAreaInfo.get(tbpNext.getLeafPos()); + if (iStart == -1) { + iStart = ai.iStartIndex; + } + iWScount += ai.iWScount; + } + if (ai == null) { + return; + } + // Calculate total adjustment + int iAdjust = 0; + double dSpaceAdjust = context.getSpaceAdjust(); + if (dSpaceAdjust > 0.0) { + // Stretch by factor + // System.err.println("Potential stretch = " + + // (ai.ipdArea.max - ai.ipdArea.opt)); + iAdjust = (int)((double)(ai.ipdArea.max + - ai.ipdArea.opt) * dSpaceAdjust); + } else if (dSpaceAdjust < 0.0) { + // Shrink by factor + // System.err.println("Potential shrink = " + + // (ai.ipdArea.opt - ai.ipdArea.min)); + iAdjust = (int)((double)(ai.ipdArea.opt + - ai.ipdArea.min) * dSpaceAdjust); + } + // System.err.println("Text adjustment factor = " + dSpaceAdjust + + // " total=" + iAdjust); + + // Make an area containing all characters between start and end. + InlineArea word = null; + int adjust = 0; + // ingnore newline character + if (chars[ai.iBreakIndex - 1] == NEWLINE) { + adjust = 1; + } + String str = new String(chars, iStart, ai.iBreakIndex - iStart - adjust); + if (" ".equals(str)) { + word = new Space(); + word.setWidth(ai.ipdArea.opt + iAdjust); + } else { + Word w = createWord( + str, + ai.ipdArea.opt + iAdjust, context.getBaseline()); + if (iWScount > 0) { + //getLogger().error("Adjustment per word-space= " + + // iAdjust / iWScount); + w.setWSadjust(iAdjust / iWScount); + } + word = w; + } + if ((chars[iStart] == SPACE || chars[iStart] == NBSPACE) + && context.getLeadingSpace().hasSpaces()) { + context.getLeadingSpace().addSpace(halfWS); + } + // Set LAST flag if done making characters + int iLastChar; + for (iLastChar = ai.iBreakIndex; + iLastChar < chars.length && chars[iLastChar] == SPACE; + iLastChar++) { + //nop + } + context.setFlags(LayoutContext.LAST_AREA, + iLastChar == chars.length); + + // Can we have any trailing space? Yes, if last char was a space! + context.setTrailingSpace(new SpaceSpecifier(false)); + if (chars[ai.iBreakIndex - 1] == SPACE + || chars[ai.iBreakIndex - 1] == NBSPACE) { + context.getTrailingSpace().addSpace(halfWS); + } + if (word != null) { + parentLM.addChild(word); + } + } + + /** + * Create an inline word area. + * This creates a Word and sets up the various attributes. + * + * @param str the string for the word + * @param width the width that the word uses + * @param base the baseline position + * @return the new word area + */ + protected Word createWord(String str, int width, int base) { + Word curWordArea = new Word(); + curWordArea.setWidth(width); + curWordArea.setHeight(textInfo.fs.getAscender() + - textInfo.fs.getDescender()); + curWordArea.setOffset(textInfo.fs.getAscender()); + curWordArea.setOffset(base); + + curWordArea.setWord(str); + curWordArea.addTrait(Trait.FONT_NAME, textInfo.fs.getFontName()); + curWordArea.addTrait(Trait.FONT_SIZE, + new Integer(textInfo.fs.getFontSize())); + curWordArea.addTrait(Trait.COLOR, this.textInfo.color); + return curWordArea; + } + +} + diff --git a/src/java/org/apache/fop/layoutmgr/TraitSetter.java b/src/java/org/apache/fop/layoutmgr/TraitSetter.java new file mode 100644 index 000000000..973684144 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/TraitSetter.java @@ -0,0 +1,187 @@ +/* + * $Id: TraitSetter.java,v 1.6 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr; + +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.area.Area; +import org.apache.fop.area.Trait; +import org.apache.fop.layout.BackgroundProps; + +/** + * This is a helper class used for setting common traits on areas. + */ +public class TraitSetter { + + /** + * Sets border and padding traits on areas. + * @param area area to set the traits on + * @param bpProps border and padding properties + */ + public static void setBorderPaddingTraits(Area area, + BorderAndPadding bpProps, boolean bNotFirst, boolean bNotLast) { + int iBP; + iBP = bpProps.getPadding(BorderAndPadding.START, bNotFirst); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_START, new Integer(iBP))); + area.addTrait(Trait.PADDING_START, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.END, bNotLast); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_END, new Integer(iBP))); + area.addTrait(Trait.PADDING_END, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.BEFORE, false); + if (iBP > 0) { + // area.addTrait(new Trait(Trait.PADDING_BEFORE, new Integer(iBP))); + area.addTrait(Trait.PADDING_BEFORE, new Integer(iBP)); + } + iBP = bpProps.getPadding(BorderAndPadding.AFTER, false); + if (iBP > 0) { + //area.addTrait(new Trait(Trait.PADDING_AFTER, new Integer(iBP))); + area.addTrait(Trait.PADDING_AFTER, new Integer(iBP)); + } + + addBorderTrait(area, bpProps, bNotFirst, + BorderAndPadding.START, Trait.BORDER_START); + + addBorderTrait(area, bpProps, bNotLast, BorderAndPadding.END, + Trait.BORDER_END); + + addBorderTrait(area, bpProps, false, BorderAndPadding.BEFORE, + Trait.BORDER_BEFORE); + + addBorderTrait(area, bpProps, false, BorderAndPadding.AFTER, + Trait.BORDER_AFTER); + } + + /** + * Sets border traits on an area. + * @param area area to set the traits on + * @param bpProps border and padding properties + */ + private static void addBorderTrait(Area area, + BorderAndPadding bpProps, + boolean bDiscard, int iSide, + Object oTrait) { + int iBP = bpProps.getBorderWidth(iSide, bDiscard); + if (iBP > 0) { + // area.addTrait(new Trait(oTrait, + // new BorderProps(bpProps.getBorderStyle(iSide), + // iBP, + // bpProps.getBorderColor(iSide)))); + area.addTrait(oTrait, + new BorderProps(bpProps.getBorderStyle(iSide), + iBP, bpProps.getBorderColor(iSide))); + } + } + + /** + * Add borders to an area. + * Layout managers that create areas with borders can use this to + * add the borders to the area. + * @param curBlock area to set the traits on + * @param bordProps border properties + */ + public static void addBorders(Area curBlock, BorderAndPadding bordProps) { + BorderProps bps = getBorderProps(bordProps, BorderAndPadding.TOP); + if (bps.width != 0) { + curBlock.addTrait(Trait.BORDER_BEFORE, bps); + } + bps = getBorderProps(bordProps, BorderAndPadding.BOTTOM); + if (bps.width != 0) { + curBlock.addTrait(Trait.BORDER_AFTER, bps); + } + bps = getBorderProps(bordProps, BorderAndPadding.LEFT); + if (bps.width != 0) { + curBlock.addTrait(Trait.BORDER_START, bps); + } + bps = getBorderProps(bordProps, BorderAndPadding.RIGHT); + if (bps.width != 0) { + curBlock.addTrait(Trait.BORDER_END, bps); + } + } + + private static BorderProps getBorderProps(BorderAndPadding bordProps, int side) { + BorderProps bps; + bps = new BorderProps(bordProps.getBorderStyle(side), + bordProps.getBorderWidth(side, false), + bordProps.getBorderColor(side)); + return bps; + } + + /** + * Add background to an area. + * Layout managers that create areas with a background can use this to + * add the background to the area. + * @param curBlock the current block + * @param backProps the background properties + */ + public static void addBackground(Area curBlock, BackgroundProps backProps) { + Trait.Background back = new Trait.Background(); + back.setColor(backProps.backColor); + + if (backProps.backImage != null) { + back.setURL(backProps.backImage); + back.setRepeat(backProps.backRepeat); + if (backProps.backPosHorizontal != null) { + back.setHoriz(backProps.backPosHorizontal.getValue()); + } + if (backProps.backPosVertical != null) { + back.setVertical(backProps.backPosVertical.getValue()); + } + } + + if (back.getColor() != null || back.getURL() != null) { + curBlock.addTrait(Trait.BACKGROUND, back); + } + } +} diff --git a/src/java/org/apache/fop/layoutmgr/list/Item.java b/src/java/org/apache/fop/layoutmgr/list/Item.java new file mode 100644 index 000000000..1b1e0d511 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/list/Item.java @@ -0,0 +1,286 @@ +/* + * $Id: Item.java,v 1.11 2003/03/07 07:58:52 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-cell FO. + * A cell contains blocks. These blocks fill the cell. + */ +public class Item extends BlockStackingLayoutManager { + + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private List childBreaks = new ArrayList(); + + private int xoffset; + private int itemIPD; + + /** + * Create a new Cell layout manager. + */ + public Item() { + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility for this cell. + * A cell contains blocks so there are breaks around the blocks + * and inside the blocks. + * + * @param context the layout context + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + itemIPD = context.getRefIPD(); + + while ((curLM = getChildLM()) != null) { + if (curLM.generatesInlineAreas()) { + // error + curLM.setFinished(true); + continue; + } + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + boolean over = false; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Set the x offset of this list item. + * This offset is used to set the absolute position + * of the list item within the parent block area. + * + * @param off the x offset + */ + public void setXOffset(int off) { + xoffset = off; + } + + /** + * Add the areas for the break points. + * The list item contains block stacking layout managers + * that add block areas. + * + * @param parentIter the iterator of the break positions + * @param layoutContext the layout context for adding the areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + if (borderProps != null) { + TraitSetter.addBorders(curBlockArea, borderProps); + } + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area to get the parent for + * @return the parent area + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + curBlockArea.setPositioning(Block.ABSOLUTE); + // set position + curBlockArea.setXOffset(xoffset); + curBlockArea.setWidth(itemIPD); + //curBlockArea.setHeight(); + + // Set up dimensions + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the list item area. + * + * @param childArea the child to add to the cell + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of the layout. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } else { + setFinished(false); + //reset(resetPos); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java new file mode 100644 index 000000000..829f5289b --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java @@ -0,0 +1,275 @@ +/* + * $Id: ListBlockLayoutManager.java,v 1.11 2003/03/07 07:58:52 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a list-block FO. + * A list block contains list items which are stacked within + * the list block area.. + */ +public class ListBlockLayoutManager extends BlockStackingLayoutManager { + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private List bodyBreaks = new ArrayList(); + + private class SectionPosition extends LeafPosition { + protected List list; + protected SectionPosition(LayoutProcessor lm, int pos, List l) { + super(lm, pos); + list = l; + } + } + + /** + * Create a new table layout manager. + * + */ + public ListBlockLayoutManager() { + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility. + * The break possibility depends on the height of the header and footer + * and possible breaks inside the table body. + * + * @param context the layout context for finding breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + // currently active LM + LayoutProcessor curLM; + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + while ((curLM = (LayoutProcessor)getChildLM()) != null) { + // Make break positions + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + boolean over = false; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + bodyBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, bodyBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * The table area is a reference area that contains areas for + * columns, bodies, rows and the contents are in cells. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + // the list block contains areas stacked from each list item + + int listHeight = 0; + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(bodyBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = (LayoutProcessor)breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + if (borderProps != null) { + TraitSetter.addBorders(curBlockArea, borderProps); + } + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + + flush(); + + bodyBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent area of the child + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child area to this layout manager. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + bodyBreaks.clear(); + reset(null); + } else { + + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java new file mode 100644 index 000000000..ab9cc67a3 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java @@ -0,0 +1,339 @@ +/* + * $Id: ListItemLayoutManager.java,v 1.12 2003/03/07 07:58:52 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.list; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a list-item FO. + * The list item contains a list item label and a list item body. + */ +public class ListItemLayoutManager extends BlockStackingLayoutManager { + private Item label; + private Item body; + + private Block curBlockArea = null; + + private List cellList = null; + private int listItemHeight; + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private class ItemPosition extends LeafPosition { + protected List cellBreaks; + protected ItemPosition(LayoutProcessor lm, int pos, List l) { + super(lm, pos); + cellBreaks = l; + } + } + + /** + * Create a new list item layout manager. + * + */ + public ListItemLayoutManager() { + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Sets the label of the list item + * @param item the label item + */ + public void setLabel(Item item) { + label = item; + label.setParent(this); + } + + /** + * Sets the body of the list item + * @param item the body item + */ + public void setBody(Item item) { + body = item; + body.setParent(this); + } + + /** + * Get the next break possibility. + * + * @param context the layout context for getting breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + // currently active LM + Item curLM; + + label.setUserAgent(getUserAgent()); + body.setUserAgent(getUserAgent()); + + BreakPoss lastPos = null; + List breakList = new ArrayList(); + + int min = 0; + int opt = 0; + int max = 0; + + int stage = 0; + boolean over = false; + while (true) { + if (stage == 0) { + curLM = label; + } else if (stage == 1) { + curLM = body; + } else { + break; + } + List childBreaks = new ArrayList(); + MinOptMax stackSize = new MinOptMax(); + + // Set up a LayoutContext + // the ipd is from the current column + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + if (stage == 0) { + childLC.setRefIPD(24000); + } else if (stage == 1) { + childLC.setRefIPD(context.getRefIPD() - 24000); + } + stage++; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } else { + lastPos = bp; + } + stackSize.add(bp.getStackingSize()); + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + // the min is the maximum min of the label and body + if (stackSize.min > min) { + min = stackSize.min; + } + // the optimum is the minimum of all optimums + if (stackSize.opt > opt) { + opt = stackSize.opt; + } + // the maximum is the largest maximum + if (stackSize.max > max) { + max = stackSize.max; + } + + breakList.add(childBreaks); + } + listItemHeight = opt; + + MinOptMax itemSize = new MinOptMax(min, opt, max); + + if (label.isFinished() && body.isFinished()) { + setFinished(true); + } + + ItemPosition rp = new ItemPosition(this, breakList.size() - 1, breakList); + BreakPoss breakPoss = new BreakPoss(rp); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(itemSize); + return breakPoss; + } + + /** + * Add the areas for the break points. + * This sets the offset of each cell as it is added. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + Item childLM; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + ItemPosition lfp = (ItemPosition) parentIter.next(); + // Add the block areas to Area + + for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) { + List cellsbr = (List)iter.next(); + PositionIterator breakPosIter; + breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size()); + + while ((childLM = (Item)breakPosIter.getNextChildLM()) != null) { + if (childLM == body) { + childLM.setXOffset(24000); + } + childLM.addAreas(breakPosIter, lc); + } + } + } + + curBlockArea.setHeight(listItemHeight); + + flush(); + + curBlockArea = null; + } + + /** + * Get the height of the list item after adjusting. + * Should only be called after adding the list item areas. + * + * @return the height of this list item after adjustment + */ + public int getListItemHeight() { + return listItemHeight; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent are for the child + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + + // Set up dimensions + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + curBlockArea.setWidth(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child. + * Rows return the areas returned by the child elements. + * This simply adds the area to the parent layout manager. + * + * @param childArea the child area + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/Body.java b/src/java/org/apache/fop/layoutmgr/table/Body.java new file mode 100644 index 000000000..8fafaa04b --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/Body.java @@ -0,0 +1,306 @@ +/* + * $Id: Body.java,v 1.13 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-header, table-footer and table body FO. + * These fo objects have either rows or cells underneath. + * Cells are organised into rows. + */ +public class Body extends BlockStackingLayoutManager { + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private boolean rows = true; + private List columns; + + private int yoffset; + private int bodyHeight; + + private Block curBlockArea; + + private List childBreaks = new ArrayList(); + + /** + * Create a new body layout manager. + */ + public Body() { + } + + /** + * Initialize properties for this layout manager. + * + * @param propMgr the property manager from the fo object + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Set the columns from the table. + * + * @param cols the list of columns used for this body + */ + public void setColumns(List cols) { + columns = cols; + } + + /** + * Breaks for this layout manager are of the form of before + * or after a row and inside a row. + * + * @param context the layout context for finding the breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + Row curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + BreakPoss lastPos = null; + + if (columns == null) { + setFinished(true); + getLogger().warn("ignoring table body with undefined columns"); + return null; + } + + while ((curLM = (Row)getChildLM()) != null) { + // Make break positions + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + curLM.setColumns(columns); + + boolean over = false; + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + + setFinished(true); + return null; + } + + /** + * Set the y offset of this body within the table. + * This is used to set the row offsets. + * + * @param off the y offset position + */ + public void setYOffset(int off) { + yoffset = off; + } + + /** + * Add the areas for the break points. + * This sets the offset of each row as it is added. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + Row childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + int rowoffset = 0; + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + int lastheight = 0; + while ((childLM = (Row)breakPosIter.getNextChildLM()) != null) { + childLM.setYOffset(yoffset + rowoffset); + childLM.addAreas(breakPosIter, lc); + lastheight = childLM.getRowHeight(); + } + rowoffset += lastheight; + } + bodyHeight = rowoffset; + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Get the body height of the body after adjusting. + * Should only be called after adding the body areas. + * + * @return the body height of this body + */ + public int getBodyHeight() { + return bodyHeight; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent are of the child + */ + public Area getParentArea(Area childArea) { + return parentLM.getParentArea(childArea); + } + + /** + * Add the child area. + * The table-header, table-footer and table-body areas return + * the areas return by the children. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + parentLM.addChild(childArea); + } + + /** + * Reset the position of the layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } + + /** + * Create a body area. + * This area has the background and width set. + * + * @return the new body area + */ + public Area createColumnArea() { + Area curBlockArea = new Block(); + + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + return curBlockArea; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/Caption.java b/src/java/org/apache/fop/layoutmgr/table/Caption.java new file mode 100644 index 000000000..da6ebeeb8 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/Caption.java @@ -0,0 +1,241 @@ +/* + * $Id: Caption.java,v 1.9 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-caption FO. + * The table caption contains blocks that are placed beside the + * table. + */ +public class Caption extends BlockStackingLayoutManager { + + private Block curBlockArea; + + private List childBreaks = new ArrayList(); + + /** + * Create a new Caption layout manager. + * + */ + public Caption() { + } + + /** + * Get the next break position for the caption. + * + * @param context the layout context for finding breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + // if there is a caption then get the side and work out when + // to handle it + + while ((curLM = getChildLM()) != null) { + // Make break positions and return blocks! + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + // if line layout manager then set stack limit to ipd + // line LM actually generates a LineArea which is a block + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + boolean over = false; + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Add the areas to the parent. + * + * @param parentIter the position iterator of the breaks + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent area from this caption + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the caption area. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the layout position. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/Cell.java b/src/java/org/apache/fop/layoutmgr/table/Cell.java new file mode 100644 index 000000000..4ae283e8b --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/Cell.java @@ -0,0 +1,308 @@ +/* + * $Id: Cell.java,v 1.13 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-cell FO. + * A cell contains blocks. These blocks fill the cell. + */ +public class Cell extends BlockStackingLayoutManager { + + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private List childBreaks = new ArrayList(); + + private int xoffset; + private int yoffset; + private int cellIPD; + private int height; + + /** + * Create a new Cell layout manager. + */ + public Cell() { + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility for this cell. + * A cell contains blocks so there are breaks around the blocks + * and inside the blocks. + * + * @param context the layout context + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + cellIPD = context.getRefIPD(); + + while ((curLM = getChildLM()) != null) { + if (curLM.generatesInlineAreas()) { + getLogger().error("table-cell must contain block areas - ignoring"); + curLM.setFinished(true); + continue; + } + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + boolean over = false; + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Set the y offset of this cell. + * This offset is used to set the absolute position of the cell. + * + * @param off the y direction offset + */ + public void setYOffset(int off) { + yoffset = off; + } + + /** + * Set the x offset of this cell. + * This offset is used to set the absolute position of the cell. + * + * @param off the x offset + */ + public void setXOffset(int off) { + xoffset = off; + } + + /** + * Set the row height that contains this cell. + * + * @param h the height of the row + */ + public void setRowHeight(int h) { + height = h; + } + + /** + * Add the areas for the break points. + * The cell contains block stacking layout managers + * that add block areas. + * + * @param parentIter the iterator of the break positions + * @param layoutContext the layout context for adding the areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + if (borderProps != null) { + TraitSetter.addBorders(curBlockArea, borderProps); + } + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + + curBlockArea.setHeight(height); + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area to get the parent for + * @return the parent area + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + curBlockArea.setPositioning(Block.ABSOLUTE); + // set position + curBlockArea.setXOffset(xoffset); + curBlockArea.setYOffset(yoffset); + curBlockArea.setWidth(cellIPD); + //curBlockArea.setHeight(); + + // Set up dimensions + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the cell block area. + * + * @param childArea the child to add to the cell + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of the layout. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + childBreaks.clear(); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/Column.java b/src/java/org/apache/fop/layoutmgr/table/Column.java new file mode 100644 index 000000000..ec33ce022 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/Column.java @@ -0,0 +1,159 @@ +/* + * $Id: Column.java,v 1.5 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.AbstractLayoutManager; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.fo.flow.TableColumn; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +/** + * LayoutManager for a table-column FO. + * The table creates an area for the table-column background, this class + * is used to do the area creation. This is used during the layout to handle + * column properties. + */ +public class Column extends AbstractLayoutManager { + private int columnWidth; + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + /** + * Create a new column layout manager. + */ + public Column() { + } + + /** + * @see org.apache.fop.layoutmgr.LayoutManager#setFObj(FObj) + */ + public void setFObj(FObj fobj) { + super.setFObj(fobj); + columnWidth = ((TableColumn)fobj).getColumnWidth(); + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Get the next break possibility. + * Columns do not create or return any areas. + * + * @param context the layout context + * @return the break possibility, always null + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + return null; + } + + /** + * Add the areas. + * Although this adds no areas it is used to add the id + * reference of the table-column. + * + * @param parentIter the position iterator + * @param layoutContext the context + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + addID(); + } + + /** + * Get the parent area. + * This does nothing. + * + * @param childArea the child area + * @return always null + */ + public Area getParentArea(Area childArea) { + return null; + } + + /** + * Get the width of this column. + * + * @return the width of the column + */ + public int getWidth() { + return columnWidth; + } + + /** + * Create a column area. + * This area has the background and width set. + * The Body manager will then set the offset of the column. + * + * @return the new column area + */ + public Area createColumnArea() { + Area curBlockArea = new Block(); + + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + return curBlockArea; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/Row.java b/src/java/org/apache/fop/layoutmgr/table/Row.java new file mode 100644 index 000000000..e55555a1a --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/Row.java @@ -0,0 +1,417 @@ +/* + * $Id: Row.java,v 1.14 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.Iterator; +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-row FO. + * The row contains cells that are organised according to the columns. + * A break in a table row will contain breaks for each table cell. + * If there are row spanning cells then these cells belong to this row + * but effect the occupied columns of future rows. + */ +public class Row extends BlockStackingLayoutManager { + + private List cellList = null; + private List columns = null; + private int rowHeight; + private int yoffset; + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private class RowPosition extends LeafPosition { + protected List cellBreaks; + protected RowPosition(LayoutProcessor lm, int pos, List l) { + super(lm, pos); + cellBreaks = l; + } + } + + /** + * Create a new row layout manager. + * + */ + public Row() { + } + + /** + * Initialize properties for this layout manager. + * + * @param propMgr the property manager for the fo + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Set the columns from the table. + * + * @param cols the list of columns for this table + */ + public void setColumns(List cols) { + columns = cols; + } + + private void setupCells() { + cellList = new ArrayList(); + // add cells to list + while (childLMiter.hasNext()) { + curChildLM = (LayoutProcessor) childLMiter.next(); + curChildLM.setUserAgent(getUserAgent()); + curChildLM.setParent(this); + curChildLM.init(); + cellList.add(curChildLM); + } + } + + /** + * Get the layout manager for a cell. + * + * @param pos the position of the cell + * @return the cell layout manager + */ + protected Cell getCellLM(int pos) { + if (cellList == null) { + setupCells(); + } + if (pos < cellList.size()) { + return (Cell)cellList.get(pos); + } + return null; + } + + /** + * Get the next break possibility. + * A row needs to get the possible breaks for each cell + * in the row and find a suitable break across all cells. + * + * @param context the layout context for getting breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + BreakPoss lastPos = null; + List breakList = new ArrayList(); + + int min = 0; + int opt = 0; + int max = 0; + + int cellcount = 0; + boolean over = false; + + while ((curLM = getCellLM(cellcount++)) != null) { + + List childBreaks = new ArrayList(); + MinOptMax stackSize = new MinOptMax(); + + // Set up a LayoutContext + // the ipd is from the current column + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + + int size = columns.size(); + Column col; + if (cellcount > size - 1) { + col = (Column)columns.get(size - 1); + } else { + col = (Column)columns.get(cellcount - 1); + } + childLC.setRefIPD(col.getWidth()); + + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + // the min is the maximum min of all cells + if (stackSize.min > min) { + min = stackSize.min; + } + // the optimum is the maximum of all optimums + if (stackSize.opt > opt) { + opt = stackSize.opt; + } + // the maximum is the largest maximum + if (stackSize.max > max) { + max = stackSize.max; + } + + breakList.add(childBreaks); + } + rowHeight = opt; + + MinOptMax rowSize = new MinOptMax(min, opt, max); + + boolean fin = true; + cellcount = 0; + while ((curLM = getCellLM(cellcount++)) != null) { + if (!curLM.isFinished()) { + fin = false; + break; + } + } + + setFinished(fin); + RowPosition rp = new RowPosition(this, breakList.size() - 1, breakList); + BreakPoss breakPoss = new BreakPoss(rp); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(rowSize); + return breakPoss; + } + + /** + * Reset the layoutmanager "iterator" so that it will start + * with the passed Position's generating LM + * on the next call to getChildLM. + * @param pos a Position returned by a child layout manager + * representing a potential break decision. + * If pos is null, then back up to the first child LM. + */ + protected void reset(Position pos) { + LayoutProcessor curLM; // currently active LM + int cellcount = 0; + + if (pos == null) { + while ((curLM = getCellLM(cellcount++)) != null) { + curLM.resetPosition(null); + cellcount++; + } + } else { + RowPosition rpos = (RowPosition)pos; + List breaks = rpos.cellBreaks; + + while ((curLM = getCellLM(cellcount++)) != null) { + List childbreaks = (List)breaks.get(cellcount); + curLM.resetPosition((Position)childbreaks.get(childbreaks.size() - 1)); + cellcount++; + } + } + + setFinished(false); + } + + /** + * Set the y position offset of this row. + * This is used to set the position of the areas returned by this row. + * + * @param off the y offset + */ + public void setYOffset(int off) { + yoffset = off; + } + + /** + * Add the areas for the break points. + * This sets the offset of each cell as it is added. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + Cell childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + RowPosition lfp = (RowPosition) parentIter.next(); + // Add the block areas to Area + + int cellcount = 0; + int xoffset = 0; + for (Iterator iter = lfp.cellBreaks.iterator(); iter.hasNext();) { + List cellsbr = (List)iter.next(); + PositionIterator breakPosIter; + breakPosIter = new BreakPossPosIter(cellsbr, 0, cellsbr.size()); + iStartPos = lfp.getLeafPos() + 1; + + int size = columns.size(); + Column col; + if (cellcount > size - 1) { + col = (Column)columns.get(size - 1); + } else { + col = (Column)columns.get(cellcount); + cellcount++; + } + + while ((childLM = (Cell)breakPosIter.getNextChildLM()) != null) { + childLM.setXOffset(xoffset); + childLM.setYOffset(yoffset); + childLM.setRowHeight(rowHeight); + childLM.addAreas(breakPosIter, lc); + } + xoffset += col.getWidth(); + } + } + + flush(); + + } + + /** + * Get the row height of the row after adjusting. + * Should only be called after adding the row areas. + * + * @return the row height of this row after adjustment + */ + public int getRowHeight() { + return rowHeight; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent are for the child + */ + public Area getParentArea(Area childArea) { + return parentLM.getParentArea(childArea); + } + + /** + * Add the child. + * Rows return the areas returned by the child elements. + * This simply adds the area to the parent layout manager. + * + * @param childArea the child area + */ + public void addChild(Area childArea) { + parentLM.addChild(childArea); + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } + + + /** + * Get the area for this row for background. + * + * @return the row area + */ + public Area getRowArea() { + Area block = new Block(); + if (backgroundProps != null) { + TraitSetter.addBackground(block, backgroundProps); + } + return block; + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java new file mode 100644 index 000000000..5160fff11 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/TableAndCaptionLayoutManager.java @@ -0,0 +1,242 @@ +/* + * $Id: TableAndCaptionLayoutManager.java,v 1.9 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table-and-caption FO. + * A table and caption consists of a table and a caption. + * The caption contains blocks that are positioned next to the + * table on the caption side. + * The caption blocks have an implicit keep with the table. + */ +public class TableAndCaptionLayoutManager extends BlockStackingLayoutManager { + + private Block curBlockArea; + + private List childBreaks = new ArrayList(); + + /** + * Create a new table and caption layout manager. + * + */ + public TableAndCaptionLayoutManager() { + } + + /** + * Get the next break possibility. + * + * @param context the layout context for getting breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + LayoutProcessor curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + // if there is a caption then get the side and work out when + // to handle it + + while ((curLM = getChildLM()) != null) { + // Make break positions and return blocks! + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + // if line layout manager then set stack limit to ipd + // line LM actually generates a LineArea which is a block + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + boolean over = false; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + childBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, childBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Add the areas. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + LayoutProcessor childLM; + int iStartPos = 0; + LayoutContext lc = new LayoutContext(0); + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(childBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + } + } + + flush(); + + childBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area to locate the parent + * @return the area for this table and caption + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child to the current area. + * + * @param childArea the area to add + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java new file mode 100644 index 000000000..77c75f638 --- /dev/null +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -0,0 +1,398 @@ +/* + * $Id: TableLayoutManager.java,v 1.13 2003/03/07 07:58:51 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.layoutmgr.table; + +import org.apache.fop.fo.PropertyManager; +import org.apache.fop.layoutmgr.BlockStackingLayoutManager; +import org.apache.fop.layoutmgr.LayoutProcessor; +import org.apache.fop.layoutmgr.LeafPosition; +import org.apache.fop.layoutmgr.BreakPoss; +import org.apache.fop.layoutmgr.LayoutContext; +import org.apache.fop.layoutmgr.PositionIterator; +import org.apache.fop.layoutmgr.BreakPossPosIter; +import org.apache.fop.layoutmgr.Position; +import org.apache.fop.layoutmgr.TraitSetter; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.layout.BorderAndPadding; +import org.apache.fop.layout.BackgroundProps; + +import java.util.ArrayList; +import java.util.List; + +/** + * LayoutManager for a table FO. + * A table consists of columns, table header, table footer and multiple + * table bodies. + * The header, footer and body add the areas created from the table cells. + * The table then creates areas for the columns, bodies and rows + * the render background. + */ +public class TableLayoutManager extends BlockStackingLayoutManager { + private List columns = null; + private Body tableHeader = null; + private Body tableFooter = null; + + private BorderAndPadding borderProps = null; + private BackgroundProps backgroundProps; + + private Block curBlockArea; + + private List bodyBreaks = new ArrayList(); + private BreakPoss headerBreak; + private BreakPoss footerBreak; + + private class SectionPosition extends LeafPosition { + protected List list; + protected SectionPosition(LayoutProcessor lm, int pos, List l) { + super(lm, pos); + list = l; + } + } + + /** + * Create a new table layout manager. + * + */ + public TableLayoutManager() { + } + + /** + * @see org.apache.fop.layoutmgr.AbstractLayoutManager#initProperties(PropertyManager) + */ + protected void initProperties(PropertyManager propMgr) { + borderProps = propMgr.getBorderAndPadding(); + backgroundProps = propMgr.getBackgroundProps(); + } + + /** + * Set the columns for this table. + * + * @param cols the list of column layout managers + */ + public void setColumns(List cols) { + columns = cols; + } + + /** + * Set the table header. + * + * @param th the table header layout manager + */ + public void setTableHeader(Body th) { + tableHeader = th; + tableHeader.setParent(this); + } + + /** + * Set the table footer. + * + * @param tf the table footer layout manager + */ + public void setTableFooter(Body tf) { + tableFooter = tf; + tableFooter.setParent(this); + } + + /** + * Get the next break possibility. + * The break possibility depends on the height of the header and footer + * and possible breaks inside the table body. + * + * @param context the layout context for finding breaks + * @return the next break possibility + */ + public BreakPoss getNextBreakPoss(LayoutContext context) { + Body curLM; // currently active LM + + MinOptMax stackSize = new MinOptMax(); + // if starting add space before + // stackSize.add(spaceBefore); + BreakPoss lastPos = null; + + MinOptMax headerSize = null; + if (tableHeader != null) { + tableHeader.setUserAgent(getUserAgent()); + tableHeader.resetPosition(null); + headerBreak = getHeight(tableHeader, context); + headerSize = headerBreak.getStackingSize(); + stackSize.add(headerSize); + } + + MinOptMax footerSize = null; + if (tableFooter != null) { + tableFooter.setUserAgent(getUserAgent()); + tableFooter.resetPosition(null); + footerBreak = getHeight(tableFooter, context); + footerSize = footerBreak.getStackingSize(); + stackSize.add(footerSize); + } + + if (stackSize.opt > context.getStackLimit().max) { + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, 0)); + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + + while ((curLM = (Body)getChildLM()) != null) { + // Make break positions + // Set up a LayoutContext + int ipd = context.getRefIPD(); + BreakPoss bp; + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit( + MinOptMax.subtract(context.getStackLimit(), + stackSize)); + childLC.setRefIPD(ipd); + + curLM.setColumns(columns); + + boolean over = false; + while (!curLM.isFinished()) { + if ((bp = curLM.getNextBreakPoss(childLC)) != null) { + if (stackSize.opt + bp.getStackingSize().opt > context.getStackLimit().max) { + // reset to last break + if (lastPos != null) { + LayoutProcessor lm = lastPos.getLayoutManager(); + lm.resetPosition(lastPos.getPosition()); + if (lm != curLM) { + curLM.resetPosition(null); + } + } else { + curLM.resetPosition(null); + } + over = true; + break; + } + stackSize.add(bp.getStackingSize()); + lastPos = bp; + bodyBreaks.add(bp); + + if (bp.nextBreakOverflows()) { + over = true; + break; + } + + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new LeafPosition(this, bodyBreaks.size() - 1)); + if (over) { + breakPoss.setFlag(BreakPoss.NEXT_OVERFLOWS, true); + } + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + setFinished(true); + return null; + } + + /** + * Get the break possibility and height of the table header or footer. + * + * @param lm the header or footer layout manager + * @param context the parent layout context + * @return the break possibility containing the stacking size + */ + protected BreakPoss getHeight(Body lm, LayoutContext context) { + int ipd = context.getRefIPD(); + BreakPoss bp; + + MinOptMax stackSize = new MinOptMax(); + + LayoutContext childLC = new LayoutContext(0); + childLC.setStackLimit(context.getStackLimit()); + childLC.setRefIPD(ipd); + + lm.setColumns(columns); + + List breaks = new ArrayList(); + while (!lm.isFinished()) { + if ((bp = lm.getNextBreakPoss(childLC)) != null) { + stackSize.add(bp.getStackingSize()); + breaks.add(bp); + childLC.setStackLimit(MinOptMax.subtract( + context.getStackLimit(), stackSize)); + } + } + BreakPoss breakPoss = new BreakPoss( + new SectionPosition(this, breaks.size() - 1, breaks)); + breakPoss.setStackingSize(stackSize); + return breakPoss; + } + + /** + * The table area is a reference area that contains areas for + * columns, bodies, rows and the contents are in cells. + * + * @param parentIter the position iterator + * @param layoutContext the layout context for adding areas + */ + public void addAreas(PositionIterator parentIter, + LayoutContext layoutContext) { + getParentArea(null); + addID(); + + // add column, body then row areas + + int tableHeight = 0; + Body childLM; + LayoutContext lc = new LayoutContext(0); + + // add table header areas + if (headerBreak != null) { + SectionPosition pos = (SectionPosition)headerBreak.getPosition(); + List list = pos.list; + PositionIterator breakPosIter = new BreakPossPosIter(list, 0, list.size() + 1); + while ((childLM = (Body)breakPosIter.getNextChildLM()) != null) { + childLM.addAreas(breakPosIter, lc); + tableHeight += childLM.getBodyHeight(); + } + } + + int iStartPos = 0; + while (parentIter.hasNext()) { + LeafPosition lfp = (LeafPosition) parentIter.next(); + // Add the block areas to Area + PositionIterator breakPosIter = + new BreakPossPosIter(bodyBreaks, iStartPos, + lfp.getLeafPos() + 1); + iStartPos = lfp.getLeafPos() + 1; + while ((childLM = (Body)breakPosIter.getNextChildLM()) != null) { + childLM.setYOffset(tableHeight); + childLM.addAreas(breakPosIter, lc); + tableHeight += childLM.getBodyHeight(); + } + } + + // add footer areas + if (footerBreak != null) { + SectionPosition pos = (SectionPosition)footerBreak.getPosition(); + List list = pos.list; + PositionIterator breakPosIter = new BreakPossPosIter(list, 0, list.size() + 1); + while ((childLM = (Body)breakPosIter.getNextChildLM()) != null) { + childLM.setYOffset(tableHeight); + childLM.addAreas(breakPosIter, lc); + tableHeight += childLM.getBodyHeight(); + } + } + + curBlockArea.setHeight(tableHeight); + + if (borderProps != null) { + TraitSetter.addBorders(curBlockArea, borderProps); + } + if (backgroundProps != null) { + TraitSetter.addBackground(curBlockArea, backgroundProps); + } + + flush(); + + bodyBreaks.clear(); + curBlockArea = null; + } + + /** + * Return an Area which can contain the passed childArea. The childArea + * may not yet have any content, but it has essential traits set. + * In general, if the LayoutManager already has an Area it simply returns + * it. Otherwise, it makes a new Area of the appropriate class. + * It gets a parent area for its area by calling its parent LM. + * Finally, based on the dimensions of the parent area, it initializes + * its own area. This includes setting the content IPD and the maximum + * BPD. + * + * @param childArea the child area + * @return the parent area of the child + */ + public Area getParentArea(Area childArea) { + if (curBlockArea == null) { + curBlockArea = new Block(); + // Set up dimensions + // Must get dimensions from parent area + Area parentArea = parentLM.getParentArea(curBlockArea); + int referenceIPD = parentArea.getIPD(); + curBlockArea.setIPD(referenceIPD); + // Get reference IPD from parentArea + setCurrentArea(curBlockArea); // ??? for generic operations + } + return curBlockArea; + } + + /** + * Add the child area to this layout manager. + * + * @param childArea the child area to add + */ + public void addChild(Area childArea) { + if (curBlockArea != null) { + curBlockArea.addBlock((Block) childArea); + } + } + + /** + * Reset the position of this layout manager. + * + * @param resetPos the position to reset to + */ + public void resetPosition(Position resetPos) { + if (resetPos == null) { + reset(null); + } + } +} + diff --git a/src/java/org/apache/fop/mif/MIFElement.java b/src/java/org/apache/fop/mif/MIFElement.java new file mode 100644 index 000000000..76b4173dd --- /dev/null +++ b/src/java/org/apache/fop/mif/MIFElement.java @@ -0,0 +1,149 @@ +/* + * $Id: MIFElement.java,v 1.3 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +/** + * The is the basis for MIF document elements. + * This enables the creation of the element and to write it + * to an output stream including sub-elements or a single value. + */ +public class MIFElement { + protected String name; + protected String valueStr = null; + protected List valueElements = null; + + protected boolean started = false; + protected boolean finish = false; + protected boolean finished = false; + + /** + */ + public MIFElement(String n) { + name = n; + } + + public void setValue(String str) { + valueStr = str; + } + + public void addElement(MIFElement el) { + if (valueElements == null) { + valueElements = new java.util.ArrayList(); + } + valueElements.add(el); + } + + /** + * Output this element to an output stream. + * This will output only so far as the fisrt unfinished child element. + * This method can be called again to continue from the previous point. + * An element that contains child elements will only be finished when + * the finish method is called. + */ + public boolean output(OutputStream os, int indent) throws IOException { + if (finished) { + return true; + } + if (valueElements == null && valueStr == null) { + return false; + } + + String indentStr = ""; + for (int c = 0; c < indent; c++) { + indentStr += " "; + } + if (!started) { + os.write((indentStr + "<" + name).getBytes()); + if (valueElements != null) { + os.write(("\n").getBytes()); + } + started = true; + } + if (valueElements != null) { + boolean done = true; + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + boolean d = el.output(os, indent + 1); + if (d) { + iter.remove(); + } else { + done = false; + break; + } + } + if (!finish || !done) { + return false; + } + os.write((indentStr + "> # end of " + name + "\n").getBytes()); + } else { + os.write((" " + valueStr + ">\n").getBytes()); + } + finished = true; + return true; + } + + public void finish(boolean deep) { + finish = true; + if (deep && valueElements != null) { + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + el.finish(deep); + } + } + } +} + diff --git a/src/java/org/apache/fop/mif/MIFFile.java b/src/java/org/apache/fop/mif/MIFFile.java new file mode 100644 index 000000000..e467af1af --- /dev/null +++ b/src/java/org/apache/fop/mif/MIFFile.java @@ -0,0 +1,169 @@ +/* + * $Id: MIFFile.java,v 1.2 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; + +/** + * The MIF File. + * This organises the MIF File and the corresponding elements. + * The catalog elements are used to setup the resources that + * are referenced. + */ +public class MIFFile extends MIFElement { + + protected MIFElement colorCatalog = null; + protected PGFElement pgfCatalog = null; + protected MIFElement fontCatalog = null; + protected RulingElement rulingCatalog = null; + protected MIFElement tblCatalog = null; + protected MIFElement views = null; + protected MIFElement variableFormats = null; + protected MIFElement xRefFormats = null; + protected MIFElement document = null; + protected MIFElement bookComponent = null; + protected MIFElement initialAutoNums = null; + protected MIFElement aFrames = null; + protected MIFElement tbls = null; + protected List pages = new java.util.ArrayList(); + protected List textFlows = null; + + + public MIFFile() { + super(""); + valueElements = new java.util.ArrayList(); + setup(); + } + + /** + * Do some setup. + * Currently adds some dummy values to the resources. + */ + protected void setup() { + MIFElement unit = new MIFElement("Units"); + unit.setValue("Ucm"); + addElement(unit); + + colorCatalog = new MIFElement("ColorCatalog"); + MIFElement color = new MIFElement("Color"); + MIFElement prop = new MIFElement("ColorTag"); + prop.setValue("`Black'"); + color.addElement(prop); + prop = new MIFElement("ColorCyan"); + prop.setValue("0.000000"); + color.addElement(prop); + + prop = new MIFElement("ColorMagenta"); + prop.setValue("0.000000"); + color.addElement(prop); + prop = new MIFElement("ColorYellow"); + prop.setValue("0.000000"); + color.addElement(prop); + prop = new MIFElement("ColorBlack"); + prop.setValue("100.000000"); + color.addElement(prop); + prop = new MIFElement("ColorAttribute"); + prop.setValue("ColorIsBlack"); + color.addElement(prop); + prop = new MIFElement("ColorAttribute"); + prop.setValue("ColorIsReserved"); + color.addElement(prop); + color.finish(true); + + colorCatalog.addElement(color); + addElement(colorCatalog); + + pgfCatalog = new PGFElement(); + pgfCatalog.lookupElement(null); + addElement(pgfCatalog); + + rulingCatalog = new RulingElement(); + rulingCatalog.lookupElement(null); + addElement(rulingCatalog); + + } + + public void output(OutputStream os) throws IOException { + if (finished) { + return; + } + + if (!started) { + os.write((" # Generated by FOP\n"/* + getVersion()*/).getBytes()); + started = true; + } + boolean done = true; + + for (Iterator iter = valueElements.iterator(); iter.hasNext();) { + MIFElement el = (MIFElement)iter.next(); + boolean d = el.output(os, 0); + if (d) { + iter.remove(); + } else { + done = false; + break; + } + } + if (done && finish) { + os.write(("# end of MIFFile").getBytes()); + } + } + + public void addPage(MIFElement p) { + pages.add(p); + addElement(p); + } +} + diff --git a/src/java/org/apache/fop/mif/MIFHandler.java b/src/java/org/apache/fop/mif/MIFHandler.java new file mode 100644 index 000000000..3418e09d2 --- /dev/null +++ b/src/java/org/apache/fop/mif/MIFHandler.java @@ -0,0 +1,251 @@ +/* + * $Id: MIFHandler.java,v 1.6 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +// Java +import java.io.IOException; +import java.io.OutputStream; + +// XML +import org.xml.sax.SAXException; + +// FOP +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.fo.Title; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.Flow; +import org.apache.fop.fo.pagination.LayoutMasterSet; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.PageSequenceMaster; +import org.apache.fop.fo.pagination.SimplePageMaster; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.apps.FOPException; + +// TODO: do we really want every method throwing a SAXException + +/** + * The MIF Handler. + * This generates MIF output using the structure events from + * the FO Tree sent to this structure handler. + * This builds an MIF file and writes it to the output. + */ +public class MIFHandler extends StructureHandler { + + /** the MIFFile instance */ + protected MIFFile mifFile; + /** the OutputStream to write to */ + protected OutputStream outStream; + private FontInfo fontInfo = new FontInfo(); + + // current state elements + private MIFElement textFlow; + private MIFElement para; + + /** + * Creates a new MIF handler on a given OutputStream. + * @param os OutputStream to write to + */ + public MIFHandler(OutputStream os) { + outStream = os; + // use pdf fonts for now, this is only for resolving names + org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); + } + + /** + * @see org.apache.fop.apps.StructureHandler#getFontInfo() + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + /** + * @see org.apache.fop.apps.StructureHandler#startDocument() + */ + public void startDocument() throws SAXException { + mifFile = new MIFFile(); + try { + mifFile.output(outStream); + } catch (IOException ioe) { + throw new SAXException(ioe); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler#endDocument() + */ + public void endDocument() throws SAXException { + // finish all open elements + mifFile.finish(true); + try { + mifFile.output(outStream); + outStream.flush(); + } catch (IOException ioe) { + throw new SAXException(ioe); + } + } + + /** + * Start the page sequence. + * This creates the pages in the MIF document that will be used + * by the following flows and static areas. + * @see org.apache.fop.apps.StructureHandler + */ + public void startPageSequence(PageSequence pageSeq, Title seqTitle, LayoutMasterSet lms) { + // get the layout master set + // setup the pages for this sequence + String name = pageSeq.getProperty("master-reference").getString(); + SimplePageMaster spm = lms.getSimplePageMaster(name); + if (spm == null) { + PageSequenceMaster psm = lms.getPageSequenceMaster(name); + } else { + // create simple master with regions + MIFElement prop = new MIFElement("PageType"); + prop.setValue("BodyPage"); + + MIFElement page = new MIFElement("Page"); + page.addElement(prop); + + prop = new MIFElement("PageBackground"); + prop.setValue("'Default'"); + page.addElement(prop); + + // build regions + MIFElement textRect = new MIFElement("TextRect"); + prop = new MIFElement("ID"); + prop.setValue("1"); + textRect.addElement(prop); + prop = new MIFElement("ShapeRect"); + prop.setValue("0.0 841.889 453.543 0.0"); + textRect.addElement(prop); + page.addElement(textRect); + + textRect = new MIFElement("TextRect"); + prop = new MIFElement("ID"); + prop.setValue("2"); + textRect.addElement(prop); + prop = new MIFElement("ShapeRect"); + prop.setValue("0.0 841.889 453.543 187.65"); + textRect.addElement(prop); + page.addElement(textRect); + + + + mifFile.addPage(page); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler#endPageSequence(PageSequence) + */ + public void endPageSequence(PageSequence pageSeq) throws FOPException { + + } + + /** + * @see org.apache.fop.apps.StructureHandler#startFlow(Flow) + */ + public void startFlow(Flow fl) { + // start text flow in body region + textFlow = new MIFElement("TextFlow"); + } + + /** + * @see org.apache.fop.apps.StructureHandler#endFlow(Flow) + */ + public void endFlow(Flow fl) { + textFlow.finish(true); + mifFile.addElement(textFlow); + textFlow = null; + } + + /** + * @see org.apache.fop.apps.StructureHandler#startBlock(Block) + */ + public void startBlock(Block bl) { + para = new MIFElement("Para"); + // get font + textFlow.addElement(para); + } + + /** + * @see org.apache.fop.apps.StructureHandler#endBlock(Block) + */ + public void endBlock(Block bl) { + para.finish(true); + para = null; + } + + /** + * @see org.apache.fop.apps.StructureHandler#characters(char[], int, int) + */ + public void characters(char data[], int start, int length) { + if (para != null) { + String str = new String(data, start, length); + str = str.trim(); + // break into nice length chunks + if (str.length() == 0) { + return; + } + + MIFElement line = new MIFElement("ParaLine"); + MIFElement prop = new MIFElement("TextRectID"); + prop.setValue("2"); + line.addElement(prop); + prop = new MIFElement("String"); + prop.setValue("\"" + str + "\""); + line.addElement(prop); + + para.addElement(line); + } + } + +} + diff --git a/src/java/org/apache/fop/mif/PGFElement.java b/src/java/org/apache/fop/mif/PGFElement.java new file mode 100644 index 000000000..3677c77b8 --- /dev/null +++ b/src/java/org/apache/fop/mif/PGFElement.java @@ -0,0 +1,80 @@ +/* + * $Id: PGFElement.java,v 1.2 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +/** + * Font Catalog element. + * This is the reference lookup element for fonts in + * the MIF document. + */ +public class PGFElement extends RefElement { + + /** + * Creates a new font catalog element. + */ + public PGFElement() { + super("PgfCatalog"); + } + + public MIFElement lookupElement(Object key) { + if (key == null) { + MIFElement pgf = new MIFElement("Pgf"); + MIFElement prop = new MIFElement("PgfTag"); + prop.setValue("`Body'"); + pgf.addElement(prop); + addElement(pgf); + pgf.finish(true); + return pgf; + } + return null; + } +} + diff --git a/src/java/org/apache/fop/mif/RefElement.java b/src/java/org/apache/fop/mif/RefElement.java new file mode 100644 index 000000000..c1dafcf08 --- /dev/null +++ b/src/java/org/apache/fop/mif/RefElement.java @@ -0,0 +1,75 @@ +/* + * $Id: RefElement.java,v 1.2 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +/** + * Reference MIF Element. + * This element is a lookup reference set that contains + * a list of resources used in the MIF Document. + * When a lookup is performed it will either create a new + * element or return an existing element that is valid. + * THe key depends on the type of reference, it should be able + * to uniquely identify the element. + */ +public class RefElement extends MIFElement { + + /** + * @see org.apache.fop.mif.MIFElement#MIFElement(String) + */ + public RefElement(String n) { + super(n); + } + + public MIFElement lookupElement(Object key) { + return null; + } +} + diff --git a/src/java/org/apache/fop/mif/RulingElement.java b/src/java/org/apache/fop/mif/RulingElement.java new file mode 100644 index 000000000..ba9e32b77 --- /dev/null +++ b/src/java/org/apache/fop/mif/RulingElement.java @@ -0,0 +1,82 @@ +/* + * $Id: RulingElement.java,v 1.2 2003/03/07 08:09:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.mif; + +public class RulingElement extends RefElement { + + public RulingElement() { + super("RulingCatalog"); + } + + public MIFElement lookupElement(Object key) { + if (key == null) { + MIFElement rul = new MIFElement("Ruling"); + MIFElement prop = new MIFElement("RulingTag"); + prop.setValue("`Default'"); + rul.addElement(prop); + prop = new MIFElement("RulingPenWidth"); + prop.setValue("1"); + rul.addElement(prop); + prop = new MIFElement("RulingPen"); + prop.setValue("0"); + rul.addElement(prop); + prop = new MIFElement("RulingLines"); + prop.setValue("1"); + rul.addElement(prop); + + addElement(rul); + rul.finish(true); + return rul; + } + return null; + } +} + diff --git a/src/java/org/apache/fop/pdf/ASCII85Filter.java b/src/java/org/apache/fop/pdf/ASCII85Filter.java new file mode 100644 index 000000000..fdec499bc --- /dev/null +++ b/src/java/org/apache/fop/pdf/ASCII85Filter.java @@ -0,0 +1,242 @@ +/* + * $Id: ASCII85Filter.java,v 1.7 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; + +/** + * PDF Filter for ASCII85. + * This applies a filter to a pdf stream that converts + * the data to ASCII. + */ +public class ASCII85Filter extends PDFFilter { + private static final char ASCII85_ZERO = 'z'; + private static final char ASCII85_START = '!'; + private static final String ASCII85_EOD = "~>"; + + private static final long BASE85_4 = 85; + //private static final long base85_3 = base85_4 * base85_4; + //private static final long base85_2 = base85_3 * base85_4; + //private static final long base85_1 = base85_2 * base85_4; + + /** + * Get the PDF name of this filter. + * + * @return the name of the filter to be inserted into the PDF + */ + public String getName() { + return "/ASCII85Decode"; + } + + /** + * Get the decode parameters. + * + * @return always null + */ + public String getDecodeParms() { + return null; + } + + /** + * Encode a pdf stream using this filter. + * + * @param in the input stream to read the data from + * @param out the output stream to write the data + * @param length the length of the data to filter + * @throws IOException if there is an error reading or writing to the streams + */ + public void encode(InputStream in, OutputStream out, int length) throws IOException { + + int i; + int total = 0; + int diff = 0; + + // first encode the majority of the data + // each 4 byte group becomes a 5 byte group + for (i = 0; i + 3 < length; i += 4) { + + long val = ((in.read() << 24) + & 0xff000000L) // note: must have the L at the + + ((in.read() << 16) & 0xff0000L) // end, otherwise you get into + + ((in.read() << 8) & 0xff00L) // weird signed value problems + + (in.read() & 0xffL); // cause we're using a full 32 bits + byte[] conv = convertWord(val); + + out.write(conv, 0, conv.length); + + } + + // now take care of the trailing few bytes. + // with n leftover bytes, we append 0 bytes to make a full group of 4 + // then convert like normal (except not applying the special zero rule) + // and write out the first n+1 bytes from the result + if (i < length) { + int n = length - i; + byte[] lastdata = new byte[4]; + for (int j = 0; j < 4; j++) { + if (j < n) { + lastdata[j] = (byte)in.read(); + } else { + lastdata[j] = 0; + } + } + + long val = ((lastdata[0] << 24) & 0xff000000L) + + ((lastdata[1] << 16) & 0xff0000L) + + ((lastdata[2] << 8) & 0xff00L) + + (lastdata[3] & 0xffL); + byte[] conv = convertWord(val); + + // special rule for handling zeros at the end + if (val == 0) { + conv = new byte[5]; + for (int j = 0; j < 5; j++) { + conv[j] = (byte)'!'; + } + } + // assert n+1 <= 5 + out.write(conv, 0, n + 1); + // System.out.println("ASCII85 end of data was "+n+" bytes long"); + + } + // finally write the two character end of data marker + out.write(ASCII85_EOD.getBytes(), 0, + ASCII85_EOD.getBytes().length); + + + // assert that we have the correct outgoing length + /* + * int in = (data.length % 4); + * int out = (result.length-ASCII85_EOD.getBytes().length) % 5; + * if ((in+1 != out) && !(in == 0 && out == 0)) { + * System.out.println("ASCII85 assertion failed:"); + * System.out.println("inlength = "+data.length+" inlength % 4 = " + * + (data.length % 4)+" outlength = " + * + (result.length-ASCII85_EOD.getBytes().length) + * + " outlength % 5 = " + * + ((result.length-ASCII85_EOD.getBytes().length) % 5)); + * } + */ + + out.close(); + } + + /** + * This converts a 32 bit value (4 bytes) into 5 bytes using base 85. + * each byte in the result starts with zero at the '!' character so + * the resulting base85 number fits into printable ascii chars + * + * @param word the 32 bit unsigned (hence the long datatype) word + * @return 5 bytes (or a single byte of the 'z' character for word + * values of 0) + */ + private byte[] convertWord(long word) { + word = word & 0xffffffff; + if (word < 0) { + word = -word; + } + + if (word == 0) { + byte[] result = { + (byte)ASCII85_ZERO + }; + return result; + } else { + /* + byte c1 = (byte)((word / base85_1) & 0xFF); + byte c2 = (byte)(((word - (c1 * base85_1)) / base85_2) & 0xFF); + byte c3 = + (byte)(((word - (c1 * base85_1) - (c2 * base85_2)) / base85_3) + & 0xFF); + byte c4 = (byte)(((word - (c1 * base85_1) + - (c2 * base85_2) - (c3 * base85_3)) / base85_4) + & 0xFF); + byte c5 = (byte)(((word - (c1 * base85_1) + - (c2 * base85_2) - (c3 * base85_3) - (c4 * base85_4))) + & 0xFF); + + byte[] ret = { + (byte)(c1 + ASCII85_START), (byte)(c2 + ASCII85_START), + (byte)(c3 + ASCII85_START), (byte)(c4 + ASCII85_START), + (byte)(c5 + ASCII85_START) + }; + */ + + byte c5 = (byte)((word % BASE85_4) + ASCII85_START); + word = word / BASE85_4; + byte c4 = (byte)((word % BASE85_4) + ASCII85_START); + word = word / BASE85_4; + byte c3 = (byte)((word % BASE85_4) + ASCII85_START); + word = word / BASE85_4; + byte c2 = (byte)((word % BASE85_4) + ASCII85_START); + word = word / BASE85_4; + byte c1 = (byte)((word % BASE85_4) + ASCII85_START); + + byte[] ret = { + c1 , c2, c3, c4, c5 + }; + + for (int i = 0; i < ret.length; i++) { + if (ret[i] < 33 || ret[i] > 117) { + System.out.println("illegal char value " + + new Integer(ret[i])); + } + } + + return ret; + + + } + } + +} diff --git a/src/java/org/apache/fop/pdf/ASCIIHexFilter.java b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java new file mode 100644 index 000000000..52756d706 --- /dev/null +++ b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java @@ -0,0 +1,106 @@ +/* + * $Id: ASCIIHexFilter.java,v 1.5 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.IOException; + +/** + * ASCII Hex filter for PDF streams. + * This filter converts a pdf stream to ASCII hex data. + */ +public class ASCIIHexFilter extends PDFFilter { + private static final String ASCIIHEX_EOD = ">"; + + /** + * Get the name of this filter. + * + * @return the name of this filter for pdf + */ + public String getName() { + return "/ASCIIHexDecode"; + } + + /** + * Get the decode params. + * + * @return always null + */ + public String getDecodeParms() { + return null; + } + + /** + * Encode the pdf stream using this filter. + * + * @param in the input stream to read the data from + * @param out the output stream to write data to + * @param length the length of data to read from the stream + * @throws IOException if an error occurs reading or writing to + * the streams + */ + public void encode(InputStream in, OutputStream out, int length) throws IOException { + Writer writer = new OutputStreamWriter(out); + for (int i = 0; i < length; i++) { + int val = (int)(in.read() & 0xFF); + if (val < 16) { + writer.write("0"); + } + writer.write(Integer.toHexString(val)); + } + writer.write(ASCIIHEX_EOD); + writer.close(); + } + +} diff --git a/src/java/org/apache/fop/pdf/BitmapImage.java b/src/java/org/apache/fop/pdf/BitmapImage.java new file mode 100644 index 000000000..1f1d4e613 --- /dev/null +++ b/src/java/org/apache/fop/pdf/BitmapImage.java @@ -0,0 +1,239 @@ +/* + * $Id: BitmapImage.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.IOException; +import java.util.Map; + +/** + * Bitmap image. + * This is used to create a bitmap image that will be inserted + * into pdf. + */ +public class BitmapImage implements PDFImage { + private int height; + private int width; + private int bitsPerPixel; + private PDFColorSpace colorSpace; + private byte[] bitmaps; + private String maskRef; + private PDFColor transparent = null; + private String key; + private Map filters; + + /** + * Create a bitmap image. + * Creates a new bitmap image with the given data. + * + * @param k the key to be used to lookup the image + * @param width the width of the image + * @param height the height of the image + * @param data the bitmap data + * @param mask the transparancy mask reference if any + */ + public BitmapImage(String k, int width, int height, byte[] data, + String mask) { + this.key = k; + this.height = height; + this.width = width; + this.bitsPerPixel = 8; + this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + this.bitmaps = data; + maskRef = mask; + } + + /** + * Setup this image with the pdf document. + * + * @param doc the pdf document this will be inserted into + */ + public void setup(PDFDocument doc) { + filters = doc.getFilterMap(); + } + + /** + * Get the key for this image. + * This key is used by the pdf document so that it will only + * insert an image once. All other references to the same image + * will use the same XObject reference. + * + * @return the unique key to identify this image + */ + public String getKey() { + return key; + } + + /** + * Get the width of this image. + * + * @return the width of the image + */ + public int getWidth() { + return width; + } + + /** + * Get the height of this image. + * + * @return the height of the image + */ + public int getHeight() { + return height; + } + + /** + * Set the color space for this image. + * + * @param cs the pdf color space + */ + public void setColorSpace(PDFColorSpace cs) { + colorSpace = cs; + } + + /** + * Get the color space for the image data. + * Possible options are: DeviceGray, DeviceRGB, or DeviceCMYK + * + * @return the pdf doclor space + */ + public PDFColorSpace getColorSpace() { + return colorSpace; + } + + /** + * Get the number of bits per pixel. + * + * @return the number of bits per pixel + */ + public int getBitsPerPixel() { + return bitsPerPixel; + } + + /** + * Set the transparent color for this iamge. + * + * @param t the transparent color + */ + public void setTransparent(PDFColor t) { + transparent = t; + } + + /** + * Check if this image has a transparent color. + * + * @return true if it has a transparent color + */ + public boolean isTransparent() { + return transparent != null; + } + + /** + * Get the transparent color for this image. + * + * @return the transparent color if any + */ + public PDFColor getTransparentColor() { + return transparent; + } + + /** + * Get the bitmap mask reference for this image. + * Current not supported. + * + * @return the bitmap mask reference + */ + public String getMask() { + return null; + } + + /** + * Get the soft mask reference for this image. + * + * @return the soft mask reference if any + */ + public String getSoftMask() { + return maskRef; + } + + /** + * Get the pdf data stream for the bitmap data. + * + * @return a pdf stream containing the filtered image data + * @throws IOException if there is an error handling the data + */ + public PDFStream getDataStream() throws IOException { + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + imgStream.setData(bitmaps); + + imgStream.addDefaultFilters(filters, PDFStream.CONTENT_FILTER); + return imgStream; + } + + /** + * Get the ICC stream. + * @return always returns null since this has no icc color space + */ + public PDFICCStream getICCStream() { + return null; + } + + /** + * Check if this is a postscript image. + * @return always returns false + */ + public boolean isPS() { + return false; + } +} + + diff --git a/src/java/org/apache/fop/pdf/DCTFilter.java b/src/java/org/apache/fop/pdf/DCTFilter.java new file mode 100644 index 000000000..04af62b75 --- /dev/null +++ b/src/java/org/apache/fop/pdf/DCTFilter.java @@ -0,0 +1,100 @@ +/* + * $Id: DCTFilter.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.util.StreamUtilities; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * DCT Filter class. Right now it is just used as a dummy filter flag so + * we can write JPG images to the PDF. The encode method just returns the + * data passed to it. In the future an actual JPEG compression should be + * added to the encode method so other images can be compressed. + * + * @author Eric Dalquist + */ +public class DCTFilter extends PDFFilter { + + /** + * Get filter name. + * @return the pdf name for the DCT filter + */ + public String getName() { + return "/DCTDecode"; + } + + /** + * Get the decode params for this filter. + * @return the DCT filter has no decode params + */ + public String getDecodeParms() { + return null; + } + + /** + * Encode a stream with this filter. + * Currently no encoding is performed, it is assumed that the data + * is already encoded. + * @param in the input data stream + * @param out the output stream + * @param length the length of the data + * @throws IOException if there is an io error + */ + public void encode(InputStream in, OutputStream out, int length) throws IOException { + StreamUtilities.streamCopy(in, out, length); + out.close(); + } + +} + diff --git a/src/java/org/apache/fop/pdf/FlateFilter.java b/src/java/org/apache/fop/pdf/FlateFilter.java new file mode 100644 index 000000000..f830fdd09 --- /dev/null +++ b/src/java/org/apache/fop/pdf/FlateFilter.java @@ -0,0 +1,271 @@ +/* + * $Id: FlateFilter.java,v 1.7 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.util.StreamUtilities; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.util.zip.DeflaterOutputStream; + +/** + * A filter to deflate a stream. Note that the attributes for + * prediction, colors, bitsPerComponent, and columns are not supported + * when this filter is used to handle the data compression. They are + * only valid for externally encoded data such as that from a graphics + * file. + */ +public class FlateFilter extends PDFFilter { + /** + * The supported mode when this filter is used for data compression + */ + public static final int PREDICTION_NONE = 1; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_TIFF2 = 2; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_NONE = 10; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_SUB = 11; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_UP = 12; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_AVG = 13; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_PAETH = 14; + + /** + * Mode for externally encoded data. + */ + public static final int PREDICTION_PNG_OPT = 15; + + + private int predictor = PREDICTION_NONE; + private int colors; + private int bitsPerComponent; + private int columns; + + /** + * Get the name of this filter. + * + * @return the pdf name of the flate decode filter + */ + public String getName() { + return "/FlateDecode"; + } + + /** + * Get the decode params for this filter. + * + * @return a string containing the decode params for this filter + */ + public String getDecodeParms() { + if (predictor > PREDICTION_NONE) { + StringBuffer sb = new StringBuffer(); + sb.append("<< /Predictor "); + sb.append(predictor); + if (colors > 0) { + sb.append(" /Colors " + colors); + } + if (bitsPerComponent > 0) { + sb.append(" /BitsPerComponent " + bitsPerComponent); + } + if (columns > 0) { + sb.append(" /Columns " + columns); + } + sb.append(" >> "); + return sb.toString(); + } + return null; + } + + + /** + * Encode the given data and return it. Note: a side effect of + * this method is that it resets the prediction to the default + * because these attributes are not supported. So the DecodeParms + * should be retrieved after calling this method. + * + * @param in the input stream to read the data from + * @param out the output stream to write the data to + * @param length the length of data to read + * @throws IOException if there is an error reading or writing to the streams + */ + public void encode(InputStream in, OutputStream out, int length) throws IOException { + predictor = PREDICTION_NONE; + try { + DeflaterOutputStream compressedStream = + new DeflaterOutputStream(out); + StreamUtilities.streamCopy(in, compressedStream, length); + compressedStream.flush(); + compressedStream.close(); + } catch (IOException e) { + //log.error("Fatal error: " + // + e.getMessage(), e); + } + + } + + /** + * Set the predictor for this filter. + * + * @param predictor the predictor to use + * @throws PDFFilterException if there is an error with the predictor + */ + public void setPredictor(int predictor) throws PDFFilterException { + this.predictor = predictor; + + } + + /** + * Get the predictor for this filter. + * + * @return the predictor used for this filter + */ + public int getPredictor() { + return predictor; + } + + /** + * Set the colors for this filter. + * + * @param colors the colors to use + * @throws PDFFilterException if predictor is not PREDICTION_NONE + */ + public void setColors(int colors) throws PDFFilterException { + if (predictor != PREDICTION_NONE) { + this.colors = colors; + } else { + throw new PDFFilterException( + "Prediction must not be PREDICTION_NONE in" + + " order to set Colors"); + } + } + + /** + * Get the colors for this filter. + * + * @return the colors for this filter + */ + public int getColors() { + return colors; + } + + /** + * Set the number of bits per component. + * + * @param bits the number of bits per component + * @throws PDFFilterException if predictor is not PREDICTION_NONE + */ + public void setBitsPerComponent(int bits) throws PDFFilterException { + if (predictor != PREDICTION_NONE) { + bitsPerComponent = bits; + } else { + throw new PDFFilterException( + "Prediction must not be PREDICTION_NONE in order" + + " to set bitsPerComponent"); + } + } + + /** + * Get the number of bits per component. + * + * @return the number of bits per component + */ + public int getBitsPerComponent() { + return bitsPerComponent; + } + + /** + * Set the number of columns for this filter. + * + * @param columns the number of columns to use for the filter + * @throws PDFFilterException if predictor is not PREDICTION_NONE + */ + public void setColumns(int columns) throws PDFFilterException { + if (predictor != PREDICTION_NONE) { + this.columns = columns; + } else { + throw new PDFFilterException( + "Prediction must not be PREDICTION_NONE in" + + " order to set Columns"); + } + } + + /** + * Get the number of columns for this filter. + * + * @return the number of columns + */ + public int getColumns() { + return columns; + } + + +} diff --git a/src/java/org/apache/fop/pdf/InMemoryStreamCache.java b/src/java/org/apache/fop/pdf/InMemoryStreamCache.java new file mode 100644 index 000000000..bec8c6a58 --- /dev/null +++ b/src/java/org/apache/fop/pdf/InMemoryStreamCache.java @@ -0,0 +1,160 @@ +/* + * $Id: InMemoryStreamCache.java,v 1.3 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * StreamCache implementation that uses temporary files rather than heap. + */ +public class InMemoryStreamCache extends StreamCache { + + /** + * The current output stream. + */ + private ByteArrayOutputStream output; + + /** + * Creates a new InMemoryStreamCache. + */ + public InMemoryStreamCache() { + } + + /** + * Get the current OutputStream. Do not store it - it may change + * from call to call. + * @throws IOException if there is an error getting the output stream + * @return the output stream containing the data + */ + public OutputStream getOutputStream() throws IOException { + if (output == null) { + output = new ByteArrayOutputStream(); + } + return output; + } + + /** + * Filter the cache with the supplied PDFFilter. + * @param filter the filter to apply + * @throws IOException if an IO error occurs + */ + public void applyFilter(PDFFilter filter) throws IOException { + if (output == null) { + return; + } + + output.close(); + + // make inputstream from copy of outputted bytes + int size = getSize(); + ByteArrayInputStream input = + new ByteArrayInputStream(output.toByteArray()); + + // reset output + output.reset(); + + // run filter + filter.encode(input, output, size); + input.close(); + output.close(); + } + + /** + * Outputs the cached bytes to the given stream. + * @param stream the output stream to write to + * @throws IOException if there is an IO error writing to the output stream + */ + public void outputStreamData(OutputStream stream) throws IOException { + if (output == null) { + return; + } + + output.writeTo(stream); + } + + /** + * Returns the current size of the stream. + * @throws IOException if there is an error getting the size + * @return the length of the stream + */ + public int getSize() throws IOException { + if (output == null) { + return 0; + } else { + return output.size(); + } + } + + /** + * Closes the cache and frees resources. + * @throws IOException if there is an error closing the stream + */ + public void close() throws IOException { + if (output != null) { + output.close(); + output = null; + } + } + + /** + * Clears and resets the cache. + * @throws IOException if there is an error closing the stream + */ + public void reset() throws IOException { + if (output != null) { + output.close(); + output = null; + } + } +} diff --git a/src/java/org/apache/fop/pdf/PDFAction.java b/src/java/org/apache/fop/pdf/PDFAction.java new file mode 100644 index 000000000..28a1954bc --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFAction.java @@ -0,0 +1,98 @@ +/* + * $Id: PDFAction.java,v 1.6 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing an action object. + */ +public abstract class PDFAction extends PDFObject { + + + /** + * create an Action object. + * this constructor is used for passing on the object number to the PDFObject + * + * @param number the object's number + */ + public PDFAction(int number) { + + /* generic creation of object */ + super(number); + } + + /** + * empty constructor for PDFAction. + * this constructor is used when there is no additional object being created + * + */ + public PDFAction() { } + + /** + * represent the action to call + * this method should be implemented to return the action which gets + * called by the Link Object. This could be a reference to another object + * or the specific destination of the link + * + * @return the action to place next to /A within a Link + */ + public abstract String getAction(); + + + /** + * represent the object in PDF + * this method should be implemented to return the PDF which is to be + * generated by the Action object + * + * @return the PDF string + */ + public abstract byte[] toPDF(); + +} diff --git a/src/java/org/apache/fop/pdf/PDFAnnotList.java b/src/java/org/apache/fop/pdf/PDFAnnotList.java new file mode 100644 index 000000000..1953fc310 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFAnnotList.java @@ -0,0 +1,128 @@ +/* + * $Id: PDFAnnotList.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.util.Vector; + +/** + * class representing an object which is a list of annotations. + * + * This PDF object is a list of references to /Annot objects. So far we + * are dealing only with links. + */ +public class PDFAnnotList extends PDFObject { + + /** + * the /Annot objects + */ + protected Vector links = new Vector(); + + /** + * the number of /Annot objects + */ + protected int count = 0; + + /** + * create a /Annots object. + * + * @param number the object's number + */ + public PDFAnnotList(int number) { + + /* generic creation of object */ + super(number); + } + + /** + * add an /Annot object of /Subtype /Link. + * + * @param link the PDFLink to add. + */ + public void addAnnot(PDFObject link) { + this.links.addElement(link); + this.count++; + } + + /** + * get the count of /Annot objects + * + * @return the number of links + */ + public int getCount() { + return this.count; + } + + /** + * represent the object in PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(this.number + " " + this.generation + + " obj\n[\n"); + for (int i = 0; i < this.count; i++) { + p = p.append(((PDFObject)links.elementAt(i)).referencePDF() + + "\n"); + } + p = p.append("]\nendobj\n"); + return p.toString().getBytes(); + } + + /* + * example + * 20 0 obj + * [ + * 19 0 R + * ] + * endobj + */ +} diff --git a/src/java/org/apache/fop/pdf/PDFArray.java b/src/java/org/apache/fop/pdf/PDFArray.java new file mode 100644 index 000000000..6b60d416f --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFArray.java @@ -0,0 +1,93 @@ +/* + * $Id: PDFArray.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing an array object + */ +public class PDFArray extends PDFObject { + /** + * Array of calues for this pdf object. + */ + protected int[] values; + + /** + * create the array object + * + * @param number the object's number + * @param values the actual array wrapped by this object + */ + public PDFArray(int number, int[] values) { + + /* generic creation of PDF object */ + super(number); + + /* set fields using paramaters */ + this.values = values; + } + + /** + * produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + " obj\n["); + for (int i = 0; i < values.length; i++) { + p.append(" "); + p.append(values[i]); + } + p.append("]\nendobj\n"); + return p.toString().getBytes(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFCIDFont.java b/src/java/org/apache/fop/pdf/PDFCIDFont.java new file mode 100644 index 000000000..e9f3e1051 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFCIDFont.java @@ -0,0 +1,291 @@ +/* + * $Id: PDFCIDFont.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.CIDFontType; + +// based on work by Takayuki Takeuchi + +/** + * Class representing a "character identifier" font (p 210 and onwards). + */ +public class PDFCIDFont extends PDFObject { + + private String basefont; + private CIDFontType cidtype; + private Integer dw; + private PDFWArray w; + private int[] dw2; + private PDFWArray w2; + private PDFCIDSystemInfo systemInfo; + private PDFCIDFontDescriptor descriptor; + private PDFCMap cmap; + + /** + * /CIDToGIDMap (only for CIDFontType2, see p 212) + * can be either "Identity" (default) or a PDFStream + */ + private PDFStream cidMap; + + + /** + * Create the /Font object + * @param number PDF object number + * @param basefont Name of the basefont + * @param cidtype CID type + * @param dw default width + * @param w array of character widths + * @param registry name of the issuer + * @param ordering Unique name of the font + * @param supplement Supplement number + * @param descriptor CID font descriptor + */ + public PDFCIDFont(int number, String basefont, CIDFontType cidtype, int dw, + int[] w, String registry, String ordering, + int supplement, PDFCIDFontDescriptor descriptor) { + + this(number, basefont, cidtype, dw, + new PDFWArray(w), + new PDFCIDSystemInfo(registry, ordering, supplement), + descriptor); + } + + /** + * Create the /Font object + * @param number PDF object number + * @param basefont Name of the basefont + * @param cidtype CID type + * @param dw default width + * @param w array of character widths + * @param systemInfo CID system info + * @param descriptor CID font descriptor + */ + public PDFCIDFont(int number, String basefont, CIDFontType cidtype, int dw, + int[] w, PDFCIDSystemInfo systemInfo, + PDFCIDFontDescriptor descriptor) { + + this(number, basefont, cidtype, dw, + new PDFWArray(w), + systemInfo, + descriptor); + } + + /** + * Create the /Font object + * @param number PDF object number + * @param basefont Name of the basefont + * @param cidtype CID type + * @param dw default width + * @param w array of character widths + * @param systemInfo CID system info + * @param descriptor CID font descriptor + */ + public PDFCIDFont(int number, String basefont, CIDFontType cidtype, int dw, + PDFWArray w, PDFCIDSystemInfo systemInfo, + PDFCIDFontDescriptor descriptor) { + + super(number); + + this.basefont = basefont; + this.cidtype = cidtype; + this.dw = new Integer(dw); + this.w = w; + this.dw2 = null; + this.w2 = null; + this.systemInfo = systemInfo; + this.descriptor = descriptor; + this.cidMap = null; + this.cmap = null; + } + + /** + * Set the /DW attribute + * @param dw the default width + */ + public void setDW(int dw) { + this.dw = new Integer(dw); + } + + /** + * Set the /W array + * @param w the width array + */ + public void setW(PDFWArray w) { + this.w = w; + } + + /** + * Set the (two elements) /DW2 array + * @param dw2 the default metrics for vertical writing + */ + public void setDW2(int[] dw2) { + this.dw2 = dw2; + } + + /** + * Set the two elements of the /DW2 array + * @param posY position vector + * @param displacementY displacement vector + */ + public void setDW2(int posY, int displacementY) { + this.dw2 = new int[] { + posY, displacementY + }; + } + + /** + * Set the CMap used as /ToUnicode cmap + * @param cmap character map + */ + public void setCMAP(PDFCMap cmap) { + this.cmap = cmap; + } + + /** + * Set the /W2 array + * @param w2 array of metrics for vertical writing + */ + public void setW2(PDFWArray w2) { + this.w2 = w2; + } + + /** + * Set the /CIDToGIDMap (to be used only for CIDFontType2) + * @param map mapping information + */ + public void setCIDMap(PDFStream map) { + this.cidMap = map; + } + + /** + * Set the /CIDToGIDMap (to be used only for CIDFontType2) to "Identity" + */ + public void setCIDMapIdentity() { + this.cidMap = null; // not an error here, simply use the default + } + + /** + * Returns the PDF name for a certain CID font type. + * @param cidFontType CID font type + * @return corresponding PDF name + */ + protected String getPDFNameForCIDFontType(CIDFontType cidFontType) { + if (cidFontType == CIDFontType.CIDTYPE0) { + return cidFontType.getName(); + } else if (cidFontType == CIDFontType.CIDTYPE2) { + return cidFontType.getName(); + } else { + throw new IllegalArgumentException("Unsupported CID font type: " + + cidFontType.getName()); + } + } + + /** + * Produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + return toPDFString().getBytes(); + } + + /** + * Produce the PDF representation for the object + * @return the generated code + */ + public String toPDFString() { + StringBuffer p = new StringBuffer(); + p.append(this.number); + p.append(" "); + p.append(this.generation); + p.append(" obj\n<< /Type /Font"); + p.append("\n/BaseFont /"); + p.append(this.basefont); + if (cidMap != null) { + p.append(" \n/CIDToGIDMap "); + p.append(cidMap.referencePDF()); + } + p.append(" \n/Subtype /"); + p.append(getPDFNameForCIDFontType(this.cidtype)); + p.append("\n"); + p.append(systemInfo.toPDFString()); + p.append("\n/FontDescriptor "); + p.append(this.descriptor.referencePDF()); + + if (cmap != null) { + p.append("\n/ToUnicode "); + p.append(cmap.referencePDF()); + } + if (dw != null) { + p.append("\n/DW "); + p.append(this.dw); + } + if (w != null) { + p.append("\n/W "); + p.append(w.toPDFString()); + } + if (dw2 != null) { + p.append("\n/DW2 ["); // always two values, see p 211 + p.append(this.dw2[0]); + p.append(this.dw2[1]); + p.append("] \n>>\nendobj\n"); + } + if (w2 != null) { + p.append("\n/W2 "); + p.append(w2.toPDFString()); + p.append(" \n>>\nendobj\n"); + } + p.append(" \n>>\nendobj\n"); + return p.toString(); + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFCIDFontDescriptor.java b/src/java/org/apache/fop/pdf/PDFCIDFontDescriptor.java new file mode 100644 index 000000000..add7833b4 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFCIDFontDescriptor.java @@ -0,0 +1,119 @@ +/* + * $Id: PDFCIDFontDescriptor.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// based on work by Takayuki Takeuchi + +/** + * class representing a font descriptor for CID fonts. + * + * Font descriptors for CID fonts are specified on page 227 and onwards of the PDF 1.3 spec. + */ +public class PDFCIDFontDescriptor extends PDFFontDescriptor { + + /** + * The language for the font + */ + protected String lang; + + /** + * The cid set stream + */ + protected PDFStream cidSet; + + /** + * create the /FontDescriptor object + * + * @param number the object's number + * @param basefont the base font name + * @param fontBBox the bounding box for the described font + * @param flags various characteristics of the font + * @param capHeight height of the capital letters + * @param stemV the width of the dominant vertical stems of glyphs + * @param italicAngle the angle of the vertical dominant strokes + * @param lang the language + */ + public PDFCIDFontDescriptor(int number, String basefont, int[] fontBBox, + int capHeight, int flags, int italicAngle, + int stemV, String lang) { + + super(number, basefont, fontBBox[3], fontBBox[1], capHeight, flags, + new PDFRectangle(fontBBox), italicAngle, stemV); + + this.lang = lang; + } + + /** + * Set the CID set stream. + * @param cidSet the pdf stream cotnaining the CID set + */ + public void setCIDSet(PDFStream cidSet) { + this.cidSet = cidSet; + } + + /** + * Fill in the pdf data for this font descriptor. + * The charset specific dictionary entries are output. + * @param p the string buffer to append the data + */ + protected void fillInPDF(StringBuffer p) { + p.append("\n/MissingWidth 500\n"); + if (lang != null) { + p.append("\n/Lang /"); + p.append(lang); + } + if (cidSet != null) { + p.append("\n/CIDSet /"); + p.append(this.cidSet.referencePDF()); + } + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFCIDSystemInfo.java b/src/java/org/apache/fop/pdf/PDFCIDSystemInfo.java new file mode 100644 index 000000000..f5037b62f --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFCIDSystemInfo.java @@ -0,0 +1,111 @@ +/* + * $Id: PDFCIDSystemInfo.java,v 1.5 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// based on work by Takayuki Takeuchi + +/** + * class representing system information for "character identifier" fonts. + * + * this small object is used in the CID fonts and in the CMaps. + */ +public class PDFCIDSystemInfo extends PDFObject { + private String registry; + private String ordering; + private int supplement; + + /** + * Create a CID system info. + * + * @param registry the registry value + * @param ordering the ordering value + * @param supplement the supplement value + */ + public PDFCIDSystemInfo(String registry, String ordering, + int supplement) { + this.registry = registry; + this.ordering = ordering; + this.supplement = supplement; + } + + /** + * produce the PDF representation for the object. + * + * unlike the other objects, the CIDSystemInfo is written directly inside + * the referencing object + * + * @return the PDF + */ + public byte[] toPDF() { + return toPDFString().getBytes(); + } + + /** + * Create a string for the CIDSystemInfo dictionary. + * The entries are placed as an inline dictionary. + * + * @return the string for the CIDSystemInfo entry with the inline dictionary + */ + public String toPDFString() { + StringBuffer p = new StringBuffer(); + p.setLength(0); + p.append("/CIDSystemInfo << /Registry ("); + p.append(registry); + p.append(")/Ordering ("); + p.append(ordering); + p.append(")/Supplement "); + p.append(supplement); + p.append(" >>"); + return p.toString(); + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFCMap.java b/src/java/org/apache/fop/pdf/PDFCMap.java new file mode 100644 index 000000000..1cf3ae53d --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFCMap.java @@ -0,0 +1,515 @@ +/* + * $Id: PDFCMap.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * Class representing the CMap encodings. + * + * CMaps are defined in the "Predefined CJK CMap names" table. + * In section 5.6.4 of PDF reference 1.4. + */ +public class PDFCMap extends PDFStream { + + /* + * Chinese (simplified) + */ + + /** + * GB-EUC-H Microsoft Code Page 936 (lfCharSet 0x86), GB 2312-80 + * character set, EUC-CN encoding + */ + public static final String ENC_GB_EUC_H = "GB-EUC-H"; + + /** + * GB-EUC-V Vertical version of GB-EUC-H + */ + public static final String ENC_GB_EUC_V = "GB_EUC_V"; + + /** + * GBpc-EUC-H Mac OS, GB 2312-80 character set, EUC-CN encoding, Script Manager code 19 + */ + public static final String ENC_GBPC_EUC_H = "GBpc-EUC-H"; + + /** + * GBpc-EUC-V Vertical version of GBpc-EUC-H + */ + public static final String ENC_GBPC_EUC_V = "GBpc-EUC-V"; + + /** + * GBK-EUC-H Microsoft Code Page 936 (lfCharSet 0x86), GBK character set, GBK encoding + */ + public static final String ENC_GBK_EUC_H = "GBK-EUC-H"; + + /** + * GBK-EUC-V Vertical version of GBK-EUC-H + */ + public static final String ENC_GBK_EUC_V = "GBK-EUC-V"; + + /** + * GBKp-EUC-H Same as GBK-EUC-H, but replaces half-width + * Latin characters with proportional forms and maps character + * code 0x24 to a dollar sign ($) instead of a yuan symbol + */ + public static final String ENC_GBKP_EUC_H = "GBKp-EUC-H"; + + /** + * GBKp-EUC-V Vertical version of GBKp-EUC-H + */ + public static final String ENC_GBKP_EUC_V = "GBKp-EUC-V"; + + /** + * GBK2K-H GB 18030-2000 character set, mixed 1-, 2-, and 4-byte encoding + */ + public static final String ENC_GBK2K_H = "GBK2K-H"; + + /** + * GBK2K-V Vertical version of GBK2K-H + */ + public static final String ENC_GBK2K_V = "GBK2K-V"; + + /** + * UniGB-UCS2-H Unicode (UCS-2) encoding for the Adobe-GB1 character collection + */ + public static final String ENC_UNIGB_UCS2_H = "UniGB-UCS2-H"; + + /** + * UniGB-UCS2-V Vertical version of UniGB-UCS2-H + */ + public static final String ENC_UNIGB_UCS2_V = "UniGB-UCS2-V"; + + + /* + * Chinese (Traditional) + */ + + /** + * B5pc-H Mac OS, Big Five character set, Big Five encoding, Script Manager code 2 + */ + public static final String ENC_B5PC_H = "B5pc-H"; + + /** + * B5pc-V Vertical version of B5pc-H + */ + public static final String ENC_B5PC_V = "B5pc-V"; + + /** + * HKscs-B5-H Hong Kong SCS, an extension to the Big Five + * character set and encoding + */ + public static final String ENC_HKSCS_B5_H = "HKscs-B5-H"; + + /** + * HKscs-B5-V Vertical version of HKscs-B5-H + */ + public static final String ENC_HKSCS_B5_V = "HKscs-B5-V"; + + /** + * ETen-B5-H Microsoft Code Page 950 (lfCharSet 0x88), Big Five + * character set with ETen extensions + */ + public static final String ENC_ETEN_B5_H = "ETen-B5-H"; + + /** + * ETen-B5-V Vertical version of ETen-B5-H + */ + public static final String ENC_ETEN_B5_V = "ETen-B5-V"; + + /** + * ETenms-B5-H Same as ETen-B5-H, but replaces half-width + * Latin characters with proportional forms + */ + public static final String ENC_ETENMS_B5_H = "ETenms-B5-H"; + + /** + * ETenms-B5-V Vertical version of ETenms-B5-H + */ + public static final String ENC_ETENMS_B5_V = "ETenms-B5-V"; + + /** + * CNS-EUC-H CNS 11643-1992 character set, EUC-TW encoding + */ + public static final String ENC_CNS_EUC_H = "CNS-EUC-H"; + + /** + * CNS-EUC-V Vertical version of CNS-EUC-H + */ + public static final String ENC_CNS_EUC_V = "CNS-EUC-V"; + + /** + * UniCNS-UCS2-H Unicode (UCS-2) encoding for the + * Adobe-CNS1 character collection + */ + public static final String ENC_UNICNS_UCS2_H = "UniCNS-UCS2-H"; + + /** + * UniCNS-UCS2-V Vertical version of UniCNS-UCS2-H + */ + public static final String ENC_UNICNS_UCS2_V = "UniCNS-UCS2-V"; + + /* + * Japanese + */ + + /** + * 83pv-RKSJ-H Mac OS, JIS X 0208 character set with KanjiTalk6 + * extensions, Shift-JIS encoding, Script Manager code 1 + */ + public static final String ENC_83PV_RKSJ_H = "83pv-RKSJ-H"; // no V version + + /** + * 90ms-RKSJ-H Microsoft Code Page 932 (lfCharSet 0x80), JIS X 0208 + * character set with NEC and IBM extensions + */ + public static final String ENC_90MS_RKSJ_H = "90ms-RKSJ-H"; + + /** + * 90ms-RKSJ-V Vertical version of 90ms-RKSJ-H + */ + public static final String ENC_90MS_RKSJ_V = "90ms-RKSJ-V"; + + /** + * 90msp-RKSJ-H Same as 90ms-RKSJ-H, but replaces half-width Latin + * characters with proportional forms + */ + public static final String ENC_90MSP_RKSJ_H = "90msp-RKSJ-H"; + + /** + * 90msp-RKSJ-V Vertical version of 90msp-RKSJ-H + */ + public static final String ENC_90MSP_RKSJ_V = "90msp-RKSJ-V"; + + /** + * 90pv-RKSJ-H Mac OS, JIS X 0208 character set with KanjiTalk7 + * extensions, Shift-JIS encoding, Script Manager code 1 + */ + public static final String ENC_90PV_RKSJ_H = "90pv-RKSJ-H"; // no V version + + /** + * Add-RKSJ-H JIS X 0208 character set with Fujitsu FMR + * extensions, Shift-JIS encoding + */ + public static final String ENC_ADD_RKSJ_H = "Add-RKSJ-H"; + + /** + * Add-RKSJ-V Vertical version of Add-RKSJ-H + */ + public static final String ENC_ADD_RKSJ_V = "Add-RKSJ-V"; + + /** + * EUC-H JIS X 0208 character set, EUC-JP encoding + */ + public static final String ENC_EUC_H = "EUC-H"; + + /** + * EUC-V Vertical version of EUC-H + */ + public static final String ENC_EUC_V = "EUC-V"; + + /** + * Ext-RKSJ-H JIS C 6226 (JIS78) character set with + * NEC extensions, Shift-JIS encoding + */ + public static final String ENC_EXT_RKSJ_H = "Ext-RKSJ-H"; + + /** + * Ext-RKSJ-V Vertical version of Ext-RKSJ-H + */ + public static final String ENC_EXT_RKSJ_V = "Ext-RKSJ-V"; + + /** + * H JIS X 0208 character set, ISO-2022-JP encoding + */ + public static final String ENC_H = "H"; + + /** + * V Vertical version of H + */ + public static final String ENC_V = "V"; + + /** + * UniJIS-UCS2-H Unicode (UCS-2) encoding for the + * Adobe-Japan1 character collection + */ + public static final String ENC_UNIJIS_UCS2_H = "UniJIS-UCS2-H"; + + /** + * UniJIS-UCS2-V Vertical version of UniJIS-UCS2-H + */ + public static final String ENC_UNIJIS_UCS2_V = "UniJIS-UCS2-V"; + + /** + * UniJIS-UCS2-HW-H Same as UniJIS-UCS2-H, but replaces proportional + * Latin characters with half-width forms + */ + public static final String ENC_UNIJIS_UCS2_HW_H = "UniJIS-UCS2-HW-H"; + + /** + * UniJIS-UCS2-HW-V Vertical version of UniJIS-UCS2-HW-H + */ + public static final String ENC_UNIJIS_UCS2_HW_V = "UniJIS-UCS2-HW-V"; + + /* + * Korean + */ + + /** + * KSC-EUC-H KS X 1001:1992 character set, EUC-KR encoding + */ + public static final String ENC_KSC_EUC_H = "KSC-EUC-H"; + + /** + * KSC-EUC-V Vertical version of KSC-EUC-H + */ + public static final String ENC_KSC_EUC_V = "KSC-EUC-V"; + + /** + * KSCms-UHC-H Microsoft Code Page 949 (lfCharSet 0x81), KS X 1001:1992 + * character set plus 8822 additional hangul, + * Unified Hangul Code (UHC) encoding + */ + public static final String ENC_KSCMS_UHC_H = "KSCms-UHC-H"; + + /** + * KSCms-UHC-V Vertical version of KSCms-UHC-H + */ + public static final String ENC_KSCMS_UHC_V = "KSCms-UHC-V"; + + /** + * KSCms-UHC-HW-H Same as KSCms-UHC-H, but replaces proportional + * Latin characters with half-width forms + */ + public static final String ENC_KSCMS_UHC_HW_H = "KSCms-UHC-HW-H"; + + /** + * KSCms-UHC-HW-V Vertical version of KSCms-UHC-HW-H + */ + public static final String ENC_KSCMS_UHC_HW_V = "KSCms-UHC-HW-V"; + + /** + * KSCpc-EUC-H Mac OS, KS X 1001:1992 character set with + * Mac OS KH extensions, Script Manager Code 3 + */ + public static final String ENC_KSCPC_EUC_H = "KSCpc-EUC-H"; // no V version + + /** + * UniKS-UCS2-H Unicode (UCS-2) encoding for the + * Adobe-Korea1 character collection + */ + public static final String ENC_UNIKSC_UCS2_H = "UniKSC-UCS2-H"; + + /** + * UniKS-UCS2-V Vertical version of UniKS-UCS2-H + */ + public static final String ENC_UNIKSC_UCS2_V = "UniKSC-UCS2-V"; + + /* + * Generic + */ + + /** + * Identity-H The horizontal identity mapping for 2-byte CIDs; + * may be used with CIDFonts using any Registry, Ordering, and + * Supplement values. It maps 2-byte character codes ranging from + * 0 to 65,535 to the same 2-byte CID value, interpreted + * high-order byte first. + */ + public static final String ENC_IDENTITY_H = "Identity-H"; + + /** + * Identity-V Vertical version of Identity-H. The mapping + * is the same as for Identity-H. + */ + public static final String ENC_IDENTTITY_V = "Identity-V"; + + /** + * /CMapName attribute, one of the predefined constants + */ + protected String name; + + /** + * /CIDSystemInfo attribute + */ + protected PDFCIDSystemInfo sysInfo; + + /** + * horizontal writing direction + */ + public static final byte WMODE_HORIZONTAL = 0; + + /** + * vertical writing direction + */ + public static final byte WMODE_VERTICAL = 1; + + /** + * font's writing direction + */ + protected byte wMode = WMODE_HORIZONTAL; + + /** + * base CMap (String or PDFStream) + */ + protected Object base; + + /** + * create the /CMap object + * + * @param number the pdf object number + * @param name one the registered names (see Table 7.20 on p 215) + * @param sysInfo the attributes of the character collection of the CIDFont + */ + public PDFCMap(int number, String name, PDFCIDSystemInfo sysInfo) { + super(number); + this.name = name; + this.sysInfo = sysInfo; + this.base = null; + } + + /** + * set the writing direction + * + * @param mode is either WMODE_HORIZONTAL + * or WMODE_VERTICAL + */ + public void setWMode(byte mode) { + this.wMode = mode; + } + + /** + * Add the contents of this pdf object to the PDF stream. + */ + public void addContents() { + StringBuffer p = new StringBuffer(); + fillInPDF(p); + add(p.toString()); + } + + /** + * set the base CMap + * + * @param base the name of the base CMap + */ + public void setUseCMap(String base) { + this.base = base; + } + + /** + * set the base CMap + * + * @param base the stream to be used as base CMap + */ + public void setUseCMap(PDFStream base) { + this.base = base; + } + + /** + * Fill in the pdf string for this CMap. + * + * @param p the string buffer to add the pdf data to + */ + public void fillInPDF(StringBuffer p) { + // p.append("/Type /CMap\n"); + // p.append(sysInfo.toPDFString()); + // p.append("/CMapName /" + name); + // p.append("\n"); + p.append("%!PS-Adobe-3.0 Resource-CMap\n"); + p.append("%%DocumentNeededResources: ProcSet (CIDInit)\n"); + p.append("%%IncludeResource: ProcSet (CIDInit)\n"); + p.append("%%BeginResource: CMap (" + name + ")\n"); + p.append("%%EndComments\n"); + + p.append("/CIDInit /ProcSet findresource begin\n"); + p.append("12 dict begin\n"); + p.append("begincmap\n"); + + p.append("/CIDSystemInfo 3 dict dup begin\n"); + p.append(" /Registry (Adobe) def\n"); + p.append(" /Ordering (Identity) def\n"); + p.append(" /Supplement 0 def\n"); + p.append("end def\n"); + + p.append("/CMapVersion 1 def\n"); + p.append("/CMapType 1 def\n"); + p.append("/CMapName /" + name + " def\n"); + + p.append("1 begincodespacerange\n"); + p.append("<0000> \n"); + p.append("endcodespacerange\n"); + p.append("1 begincidrange\n"); + p.append("<0000> 0\n"); + p.append("endcidrange\n"); + + // p.append("1 beginbfrange\n"); + // p.append("<0020> <0100> <0000>\n"); + // p.append("endbfrange\n"); + + p.append("endcmap\n"); + p.append("CMapName currentdict /CMap defineresource pop\n"); + p.append("end\n"); + p.append("end\n"); + p.append("%%EndResource\n"); + p.append("%%EOF\n"); + /* + * p.append(" /Type /CMap\n/CMapName /" + name); + * p.append("\n"); + * p.append("\n/WMode "); p.append(wMode); + * if (base != null) { + * p.append("\n/UseCMap "); + * if (base instanceof String) { + * p.append("/"+base); + * } else {// base instanceof PDFStream + * p.append(((PDFStream)base).referencePDF()); + * } + * } + */ + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFCharProcs.java b/src/java/org/apache/fop/pdf/PDFCharProcs.java new file mode 100644 index 000000000..bcc2b9920 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFCharProcs.java @@ -0,0 +1,98 @@ +/* + * $Id: PDFCharProcs.java,v 1.4 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.Map; +import java.util.HashMap; + +/** + * class representing a /CharProcs dictionary for Type3 fonts. + * + *

CAUTION: this is not yet fully implemented!!!!!!! + * I miss an exemple of how to output this dictionary. + *

+ * + * Type3 fonts are specified on page 206 and onwards of the PDF 1.3 spec. + */ +public class PDFCharProcs extends PDFObject { + + /** + * the (character name, drawing stream) pairs for a Type3 font + */ + protected Map keys; + + /** + * Create a new PDF char proc store. + */ + public PDFCharProcs() { + keys = new HashMap(); + } + + /** + * add a character definition in the dictionary + * + * @param name the character name + * @param stream the stream that draws the character + */ + public void addCharacter(String name, PDFStream stream) { + keys.put(name, stream); + } + + /** + * not done yet + * @return the pdf byte array + */ + public byte[] toPDF() { + // todo implement this org.apache.fop.pdf.PDFObject abstract method + return new byte[0]; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFColor.java b/src/java/org/apache/fop/pdf/PDFColor.java new file mode 100644 index 000000000..90f87d6ff --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFColor.java @@ -0,0 +1,481 @@ +/* + * $Id: PDFColor.java,v 1.17 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.util.List; +import java.util.ArrayList; + +/** + * PDF Color object. + * This is used to output color to a PDF content stream. + */ +public class PDFColor extends PDFPathPaint { + // could be 3.0 as well. + private static double blackFactor = 2.0; + private double red = -1.0; + private double green = -1.0; + private double blue = -1.0; + + private double cyan = -1.0; + private double magenta = -1.0; + private double yellow = -1.0; + private double black = -1.0; + + /** + * Create a PDF color with double values ranging from 0 to 1 + * + * @param theRed the red double value + * @param theGreen the green double value + * @param theBlue the blue double value + */ + public PDFColor(double theRed, double theGreen, double theBlue) { + // super(theNumber); + this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + + this.red = theRed; + this.green = theGreen; + this.blue = theBlue; + } + + /** + * Create a PDF color with int values ranging from 0 to 255 + * + * @param theRed the red integer value + * @param theGreen the green integer value + * @param theBlue the blue integer value + */ + public PDFColor(int theRed, int theGreen, int theBlue) { + this(((double)theRed) / 255d, ((double)theGreen) / 255d, + ((double)theBlue) / 255d); + + } + + /** + * Create a PDF color with CMYK values. + * + * @param theCyan the cyan value + * @param theMagenta the magenta value + * @param theYellow the yellow value + * @param theBlack the black value + */ + public PDFColor(double theCyan, double theMagenta, double theYellow, + double theBlack) { + // super(theNumber);//? + + this.colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_CMYK); + + this.cyan = theCyan; + this.magenta = theMagenta; + this.yellow = theYellow; + this.black = theBlack; + } + + /** + * Return a vector representation of the color + * in the appropriate colorspace. + * + * @return a list containing the Double values of the color + */ + public List getVector() { + List theColorVector = new ArrayList(); + if (this.colorSpace.getColorSpace() == PDFColorSpace.DEVICE_RGB) { + // RGB + theColorVector.add(new Double(this.red)); + theColorVector.add(new Double(this.green)); + theColorVector.add(new Double(this.blue)); + } else if (this.colorSpace.getColorSpace() + == PDFColorSpace.DEVICE_CMYK) { + // CMYK + theColorVector.add(new Double(this.cyan)); + theColorVector.add(new Double(this.magenta)); + theColorVector.add(new Double(this.yellow)); + theColorVector.add(new Double(this.black)); + } else { + // GRAY + theColorVector.add(new Double(this.black)); + } + return (theColorVector); + } + + /** + * Get the red component. + * + * @return the red double value + */ + public double red() { + return (this.red); + } + + /** + * Get the green component. + * + * @return the green double value + */ + public double green() { + return (this.green); + } + + /** + * Get the blue component. + * + * @return the blue double value + */ + public double blue() { + return (this.blue); + } + + /** + * Get the red integer component. + * + * @return the red integer value + */ + public int red255() { + return (int)(this.red * 255d); + } + + /** + * Get the green integer component. + * + * @return the green integer value + */ + public int green255() { + return (int)(this.green * 255d); + } + + /** + * Get the blue integer component. + * + * @return the blue integer value + */ + public int blue255() { + return (int)(this.blue * 255d); + } + + /** + * Get the cyan component. + * + * @return the cyan double value + */ + public double cyan() { + return (this.cyan); + } + + /** + * Get the magenta component. + * + * @return the magenta double value + */ + public double magenta() { + return (this.magenta); + } + + /** + * Get the yellow component. + * + * @return the yellow double value + */ + public double yellow() { + return (this.yellow); + } + + /** + * Get the black component. + * + * @return the black double value + */ + public double black() { + return (this.black); + } + + /** + * Set the color space for this color. + * If the new color space is different the values are converted + * to the new color space. + * + * @param theColorSpace the new color space + */ + public void setColorSpace(int theColorSpace) { + int theOldColorSpace = this.colorSpace.getColorSpace(); + if (theOldColorSpace != theColorSpace) { + if (theOldColorSpace == PDFColorSpace.DEVICE_RGB) { + if (theColorSpace == PDFColorSpace.DEVICE_CMYK) { + this.convertRGBtoCMYK(); + } else { + // convert to Gray? + this.convertRGBtoGRAY(); + } + } else if (theOldColorSpace == PDFColorSpace.DEVICE_CMYK) { + if (theColorSpace == PDFColorSpace.DEVICE_RGB) { + this.convertCMYKtoRGB(); + } else { + // convert to Gray? + this.convertCMYKtoGRAY(); + } + } else { + // used to be Gray + if (theColorSpace == PDFColorSpace.DEVICE_RGB) { + this.convertGRAYtoRGB(); + } else { + // convert to CMYK? + this.convertGRAYtoCMYK(); + } + } + this.colorSpace.setColorSpace(theColorSpace); + } + } + + /** + * Get the PDF output string for this color. + * This returns the string to be inserted into PDF for setting + * the current color. + * + * @param fillNotStroke whether to return fill or stroke command + * @return the PDF string for setting the fill/stroke color + */ + public String getColorSpaceOut(boolean fillNotStroke) { + StringBuffer p = new StringBuffer(""); + + double tempDouble; + + if (this.colorSpace.getColorSpace() + == PDFColorSpace.DEVICE_RGB) { // colorspace is RGB + // according to pdfspec 12.1 p.399 + // if the colors are the same then just use the g or G operator + boolean same = false; + if (this.red == this.green && this.red == this.blue) { + same = true; + } + // output RGB + if (fillNotStroke) { + // fill + if (same) { + p.append(PDFNumber.doubleOut(this.red) + " g\n"); + } else { + p.append(PDFNumber.doubleOut(this.red) + " " + + PDFNumber.doubleOut(this.green) + " " + + PDFNumber.doubleOut(this.blue) + + " rg\n"); + } + } else { + // stroke/border + if (same) { + p.append(PDFNumber.doubleOut(this.red) + " G\n"); + } else { + p.append(PDFNumber.doubleOut(this.red) + " " + + PDFNumber.doubleOut(this.green) + " " + + PDFNumber.doubleOut(this.blue) + + " RG\n"); + } + } + } else if (this.colorSpace.getColorSpace() + == PDFColorSpace.DEVICE_CMYK) { + // colorspace is CMYK + + if (fillNotStroke) { + // fill + p.append(PDFNumber.doubleOut(this.cyan) + " " + + PDFNumber.doubleOut(this.magenta) + " " + + PDFNumber.doubleOut(this.yellow) + " " + + PDFNumber.doubleOut(this.black) + " k\n"); + } else { + // stroke + p.append(PDFNumber.doubleOut(this.cyan) + " " + + PDFNumber.doubleOut(this.magenta) + " " + + PDFNumber.doubleOut(this.yellow) + " " + + PDFNumber.doubleOut(this.black) + " K\n"); + } + + } else { + // means we're in DeviceGray or Unknown. + // assume we're in DeviceGray, because otherwise we're screwed. + + if (fillNotStroke) { + p.append(PDFNumber.doubleOut(this.black) + " g\n"); + } else { + p.append(PDFNumber.doubleOut(this.black) + " G\n"); + } + + } + return (p.toString()); + } + + /** + * Convert the color from CMYK to RGB. + */ + protected void convertCMYKtoRGB() { + // convert CMYK to RGB + this.red = 1.0 - this.cyan; + this.green = 1.0 - this.green; + this.blue = 1.0 - this.yellow; + + this.red = (this.black / PDFColor.blackFactor) + this.red; + this.green = (this.black / PDFColor.blackFactor) + this.green; + this.blue = (this.black / PDFColor.blackFactor) + this.blue; + + } + + /** + * Convert the color from RGB to CMYK. + */ + protected void convertRGBtoCMYK() { + // convert RGB to CMYK + this.cyan = 1.0 - this.red; + this.magenta = 1.0 - this.green; + this.yellow = 1.0 - this.blue; + + this.black = 0.0; + /* + * If you want to calculate black, uncomment this + * //pick the lowest color + * tempDouble = this.red; + * + * if (this.green < tempDouble) + * tempDouble = this.green; + * + * if (this.blue < tempDouble) + * tempDouble = this.blue; + * + * this.black = tempDouble / this.blackFactor; + */ + } + + /** + * Convert the color from Gray to RGB. + */ + protected void convertGRAYtoRGB() { + this.red = 1.0 - this.black; + this.green = 1.0 - this.black; + this.blue = 1.0 - this.black; + } + + /** + * Convert the color from Gray to CMYK. + */ + protected void convertGRAYtoCMYK() { + this.cyan = this.black; + this.magenta = this.black; + this.yellow = this.black; + // this.black=0.0;//? + } + + /** + * Convert the color from CMYK to Gray. + */ + protected void convertCMYKtoGRAY() { + double tempDouble = 0.0; + + // pick the lowest color + tempDouble = this.cyan; + + if (this.magenta < tempDouble) { + tempDouble = this.magenta; + } + + if (this.yellow < tempDouble) { + tempDouble = this.yellow; + } + + this.black = (tempDouble / PDFColor.blackFactor); + + } + + /** + * Convert the color from RGB to Gray. + */ + protected void convertRGBtoGRAY() { + double tempDouble = 0.0; + + // pick the lowest color + tempDouble = this.red; + + if (this.green < tempDouble) { + tempDouble = this.green; + } + + if (this.blue < tempDouble) { + tempDouble = this.blue; + } + + this.black = 1.0 - (tempDouble / PDFColor.blackFactor); + } + + /** + * Create pdf. + * Not used for this object. + * + * @return the bytes for the pdf + */ + public byte[] toPDF() { + return (new byte[0]); + } + + /** + * Check for equality of color with another object. + * + * @param obj the object to compare + * @return true if colors are equal + */ + public boolean equals(Object obj) { + if (!(obj instanceof PDFColor)) { + return false; + } + PDFColor color = (PDFColor)obj; + + if (color.red == this.red && color.green == this.green + && color.blue == this.blue) { + return true; + } + return false; + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFColorSpace.java b/src/java/org/apache/fop/pdf/PDFColorSpace.java new file mode 100644 index 000000000..10a08b57f --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFColorSpace.java @@ -0,0 +1,198 @@ +/* + * $Id: PDFColorSpace.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * PDF Color space. + */ +public class PDFColorSpace { + private boolean hasICCProfile; + private byte[] iccProfile; + private int numComponents; + + // Ok... so I had some grand purpose for this, but I can't recall. + // I'm just writing it + + /** + * Unknown colorspace + */ + public static final int DEVICE_UNKNOWN = -1; + + /** + * Gray colorspace + */ + public static final int DEVICE_GRAY = 1; + + /** + * RGB colorspace + */ + public static final int DEVICE_RGB = 2; + + /** + * CMYK colorspace + */ + public static final int DEVICE_CMYK = 3; + + // Are there any others? + + /** + * Current color space value. + */ + protected int currentColorSpace = DEVICE_UNKNOWN; + + /** + * Create a PDF colorspace object. + * + * @param theColorSpace the current colorspace + */ + public PDFColorSpace(int theColorSpace) { + this.currentColorSpace = theColorSpace; + hasICCProfile = false; + numComponents = calculateNumComponents(); + } + + private int calculateNumComponents() { + if (currentColorSpace == DEVICE_GRAY) { + return 1; + } else if (currentColorSpace == DEVICE_RGB) { + return 3; + } else if (currentColorSpace == DEVICE_CMYK) { + return 4; + } else { + return 0; + } + } + + /** + * Set the current colorspace. + * + * @param theColorSpace the new color space value + */ + public void setColorSpace(int theColorSpace) { + this.currentColorSpace = theColorSpace; + numComponents = calculateNumComponents(); + } + + /** + * Check if this colorspace has an ICC profile. + * + * @return true if this has an ICC profile + */ + public boolean hasICCProfile() { + return hasICCProfile; + } + + /** + * Get the ICC profile for this colorspace + * + * @return the byte array containing the ICC profile data + */ + public byte[] getICCProfile() { + if (hasICCProfile) { + return iccProfile; + } else { + return new byte[0]; + } + } + + /** + * Set the ICC profile for this colorspace. + * + * @param iccProfile the ICC profile data + */ + public void setICCProfile(byte[] iccProfile) { + this.iccProfile = iccProfile; + hasICCProfile = true; + } + + /** + * Get the colorspace value + * + * @return the colorspace value + */ + public int getColorSpace() { + return (this.currentColorSpace); + } + + /** + * Get the number of color components for this colorspace + * + * @return the number of components + */ + public int getNumComponents() { + return numComponents; + } + + /** + * Get the PDF string for this colorspace. + * + * @return the PDF string for the colorspace + */ + public String getColorSpacePDFString() { + // shouldn't this be a select-case? I can never remember + // the syntax for that. + switch (currentColorSpace) { + case DEVICE_CMYK: + return "DeviceCMYK"; + //break; + case DEVICE_GRAY: + return "DeviceGray"; + //break; + case DEVICE_RGB: + default: + // unknown... Error. Tell them it's RGB and hope they + // don't notice. + return ("DeviceRGB"); + //break; + } + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java new file mode 100644 index 000000000..5e9c24d79 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFDocument.java @@ -0,0 +1,1926 @@ +/* + * $Id: PDFDocument.java,v 1.63 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.util.StreamUtilities; + +import org.apache.fop.fonts.CIDFont; +import org.apache.fop.fonts.CustomFont; +import org.apache.fop.fonts.FontDescriptor; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.fonts.FontType; +import org.apache.fop.fonts.LazyFont; +import org.apache.fop.fonts.MultiByteFont; +import org.apache.fop.fonts.truetype.FontFileReader; +import org.apache.fop.fonts.truetype.TTFSubSetFile; +import org.apache.fop.fonts.type1.PFBData; +import org.apache.fop.fonts.type1.PFBParser; + +// Java +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.Iterator; +import java.awt.geom.Rectangle2D; + +/* image support modified from work of BoBoGi */ +/* font support based on work by Takayuki Takeuchi */ + +/** + * class representing a PDF document. + * + * The document is built up by calling various methods and then finally + * output to given filehandle using output method. + * + * A PDF document consists of a series of numbered objects preceded by a + * header and followed by an xref table and trailer. The xref table + * allows for quick access to objects by listing their character + * positions within the document. For this reason the PDF document must + * keep track of the character position of each object. The document + * also keeps direct track of the /Root, /Info and /Resources objects. + * + * Modified by Mark Lillywhite, mark-fop@inomial.com. The changes + * involve: ability to output pages one-at-a-time in a streaming + * fashion (rather than storing them all for output at the end); + * ability to write the /Pages object after writing the rest + * of the document; ability to write to a stream and flush + * the object list; enhanced trailer output; cleanups. + * + */ +public class PDFDocument { + private static final Integer LOCATION_PLACEHOLDER = new Integer(0); + /** + * the version of PDF supported which is 1.4 + */ + protected static final String PDF_VERSION = "1.4"; + + /** + * the encoding to use when converting strings to PDF commandos. + */ + public static final String ENCODING = "ISO-8859-1"; + + /** + * the current character position + */ + protected int position = 0; + + /** + * the character position of each object + */ + protected List location = new java.util.ArrayList(); + + /** List of objects to write in the trailer */ + private List trailerObjects = new java.util.ArrayList(); + + /** + * the counter for object numbering + */ + protected int objectcount = 0; + + /** + * the objects themselves + */ + protected List objects = new java.util.ArrayList(); + + /** + * character position of xref table + */ + protected int xref; + + /** + * the /Root object + */ + protected PDFRoot root; + + /** The root outline object */ + private PDFOutline outlineRoot = null; + + /** The /Pages object (mark-fop@inomial.com) */ + private PDFPages pages; + + /** + * the /Info object + */ + protected PDFInfo info; + + /** + * the /Resources object + */ + protected PDFResources resources; + + /** + * the colorspace (0=RGB, 1=CMYK) + */ + protected PDFColorSpace colorspace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + + /** + * the counter for Pattern name numbering (e.g. 'Pattern1') + */ + protected int patternCount = 0; + + /** + * the counter for Shading name numbering + */ + protected int shadingCount = 0; + + /** + * the counter for XObject numbering + */ + protected int xObjectCount = 0; + + /** + * the XObjects Map. + * Should be modified (works only for image subtype) + */ + protected Map xObjectsMap = new java.util.HashMap(); + + /** + * the Font Map. + */ + protected Map fontMap = new java.util.HashMap(); + + /** + * The filter map. + */ + protected Map filterMap = new java.util.HashMap(); + + /** + * List of PDFGState objects. + */ + protected List gstates = new java.util.ArrayList(); + + /** + * List of functions. + */ + protected List functions = new java.util.ArrayList(); + + /** + * List of shadings. + */ + protected List shadings = new java.util.ArrayList(); + + /** + * List of patterns. + */ + protected List patterns = new java.util.ArrayList(); + + /** + * List of Links. + */ + protected List links = new java.util.ArrayList(); + + /** + * List of FileSpecs. + */ + protected List filespecs = new java.util.ArrayList(); + + /** + * List of GoToRemotes. + */ + protected List gotoremotes = new java.util.ArrayList(); + + /** + * List of GoTos. + */ + protected List gotos = new java.util.ArrayList(); + + + /** + * creates an empty PDF document

+ * + * The constructor creates a /Root and /Pages object to + * track the document but does not write these objects until + * the trailer is written. Note that the object ID of the + * pages object is determined now, and the xref table is + * updated later. This allows Pages to refer to their + * Parent before we write it out. + * + * @param prod the name of the producer of this pdf document + */ + public PDFDocument(String prod) { + + /* create the /Root, /Info and /Resources objects */ + this.pages = makePages(); + + // Create the Root object + this.root = makeRoot(pages); + + // Create the Resources object + this.resources = makeResources(); + + // Make the /Info record + this.info = makeInfo(prod); + } + + /** + * set the producer of the document + * + * @param producer string indicating application producing the PDF + */ + public void setProducer(String producer) { + this.info.setProducer(producer); + } + + /** + * set the creator of the document + * + * @param creator string indicating application creating the document + */ + public void setCreator(String creator) { + this.info.setCreator(creator); + } + + /** + * Set the filter map to use for filters in this document. + * + * @param map the map of filter lists for each stream type + */ + public void setFilterMap(Map map) { + filterMap = map; + } + + /** + * Get the filter map used for filters in this document. + * + * @return the map of filters being used + */ + public Map getFilterMap() { + return filterMap; + } + + /** + * Make a /Catalog (Root) object. This object is written in + * the trailer. + * + * @param pages the pages pdf object that the root points to + * @return the new pdf root object for this document + */ + public PDFRoot makeRoot(PDFPages pages) { + + /* + * Make a /Pages object. This object is written in the trailer. + */ + PDFRoot pdfRoot = new PDFRoot(++this.objectcount, pages); + addTrailerObject(pdfRoot); + return pdfRoot; + } + + /** + * Get the PDF root object. + * + * @return the PDFRoot object + */ + public PDFRoot getRoot() { + return this.root; + } + + /** + * Make a /Pages object. This object is written in the trailer. + * + * @return a new PDF Pages object for adding pages to + */ + public PDFPages makePages() { + PDFPages pdfPages = new PDFPages(++this.objectcount); + addTrailerObject(pdfPages); + return pdfPages; + } + + /** + * Make a /Resources object. This object is written in the trailer. + * + * @return a new PDF resources object + */ + public PDFResources makeResources() { + PDFResources pdfResources = new PDFResources(++this.objectcount); + addTrailerObject(pdfResources); + return pdfResources; + } + + /** + * make an /Info object + * + * @param prod string indicating application producing the PDF + * @return the created /Info object + */ + protected PDFInfo makeInfo(String prod) { + + /* + * create a PDFInfo with the next object number and add to + * list of objects + */ + PDFInfo pdfInfo = new PDFInfo(++this.objectcount); + // set the default producer + pdfInfo.setProducer(prod); + this.objects.add(pdfInfo); + return pdfInfo; + } + + /** + * Get the pdf info object for this document. + * + * @return the PDF Info object for this document + */ + public PDFInfo getInfo() { + return info; + } + + /** + * Make a Type 0 sampled function + * + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List objects of Double objects. + * This is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theSize A List object of Integer objects. + * This is the number of samples in each input dimension. + * I can't imagine there being more or less than two input dimensions, + * so maybe this should be an array of length 2. + * + * See page 265 of the PDF 1.3 Spec. + * @param theBitsPerSample An int specifying the number of bits user + * to represent each sample value. + * Limited to 1,2,4,8,12,16,24 or 32. + * See page 265 of the 1.3 PDF Spec. + * @param theOrder The order of interpolation between samples. + * Default is 1 (one). Limited + * to 1 (one) or 3, which means linear or cubic-spline interpolation. + * + * This attribute is optional. + * + * See page 265 in the PDF 1.3 spec. + * @param theEncode List objects of Double objects. + * This is the linear mapping of input values intop the domain + * of the function's sample table. Default is hard to represent in + * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. + * This attribute is optional. + * + * See page 265 in the PDF 1.3 spec. + * @param theDecode List objects of Double objects. + * This is a linear mapping of sample values into the range. + * The default is just the range. + * + * This attribute is optional. + * Read about it on page 265 of the PDF 1.3 spec. + * @param theFunctionDataStream The sample values that specify + * the function are provided in a stream. + * + * This is optional, but is almost always used. + * + * Page 265 of the PDF 1.3 spec has more. + * @param theFilter This is a vector of String objects which + * are the various filters that have are to be + * applied to the stream to make sense of it. + * Order matters, so watch out. + * + * This is not documented in the Function section of the PDF 1.3 spec, + * it was deduced from samples that this is sometimes used, even if we may never + * use it in FOP. It is added for completeness sake. + * @param theFunctionType This is the type of function (0,2,3, or 4). + * It should be 0 as this is the constructor for sampled functions. + * @return the PDF function that was created + */ + public PDFFunction makeFunction(int theFunctionType, List theDomain, + List theRange, List theSize, + int theBitsPerSample, int theOrder, + List theEncode, List theDecode, + StringBuffer theFunctionDataStream, + List theFilter) { + // Type 0 function + PDFFunction function = new PDFFunction(++this.objectcount, + theFunctionType, theDomain, + theRange, theSize, + theBitsPerSample, theOrder, + theEncode, theDecode, + theFunctionDataStream, + theFilter); + + PDFFunction oldfunc = findFunction(function); + if (oldfunc == null) { + functions.add(function); + this.objects.add(function); + } else { + this.objectcount--; + function = oldfunc; + } + + return (function); + } + + /** + * make a type Exponential interpolation function + * (for shading usually) + * + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List of Doubles that is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theCZero This is a vector of Double objects which defines the function result + * when x=0. + * + * This attribute is optional. + * It's described on page 268 of the PDF 1.3 spec. + * @param theCOne This is a vector of Double objects which defines the function result + * when x=1. + * + * This attribute is optional. + * It's described on page 268 of the PDF 1.3 spec. + * @param theInterpolationExponentN This is the inerpolation exponent. + * + * This attribute is required. + * PDF Spec page 268 + * @param theFunctionType The type of the function, which should be 2. + * @return the PDF function that was created + */ + public PDFFunction makeFunction(int theFunctionType, List theDomain, + List theRange, List theCZero, + List theCOne, + double theInterpolationExponentN) { // type 2 + PDFFunction function = new PDFFunction(++this.objectcount, + theFunctionType, theDomain, + theRange, theCZero, theCOne, + theInterpolationExponentN); + PDFFunction oldfunc = findFunction(function); + if (oldfunc == null) { + functions.add(function); + this.objects.add(function); + } else { + this.objectcount--; + function = oldfunc; + } + + return (function); + } + + private Object findPDFObject(List list, PDFObject compare) { + for (Iterator iter = list.iterator(); iter.hasNext();) { + Object obj = iter.next(); + if (compare.equals(obj)) { + return obj; + } + } + return null; + } + + private PDFFunction findFunction(PDFFunction compare) { + return (PDFFunction)findPDFObject(functions, compare); + } + + private PDFShading findShading(PDFShading compare) { + return (PDFShading)findPDFObject(shadings, compare); + } + + /** + * Find a previous pattern. + * The problem with this is for tiling patterns the pattern + * data stream is stored and may use up memory, usually this + * would only be a small amount of data. + */ + private PDFPattern findPattern(PDFPattern compare) { + return (PDFPattern)findPDFObject(patterns, compare); + } + + /** + * Make a Type 3 Stitching function + * + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List objects of Double objects. + * This is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theFunctions An List of the PDFFunction objects + * that the stitching function stitches. + * + * This attributed is required. + * It is described on page 269 of the PDF spec. + * @param theBounds This is a vector of Doubles representing + * the numbers that, in conjunction with Domain + * define the intervals to which each function from + * the 'functions' object applies. It must be in + * order of increasing magnitude, and each must be + * within Domain. + * + * It basically sets how much of the gradient each function handles. + * + * This attributed is required. + * It's described on page 269 of the PDF 1.3 spec. + * @param theEncode List objects of Double objects. + * This is the linear mapping of input values intop the domain + * of the function's sample table. Default is hard to represent in + * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. + * This attribute is required. + * + * See page 270 in the PDF 1.3 spec. + * @param theFunctionType This is the function type. It should be 3, + * for a stitching function. + * @return the PDF function that was created + */ + public PDFFunction makeFunction(int theFunctionType, List theDomain, + List theRange, List theFunctions, + List theBounds, + List theEncode) { + // Type 3 + + PDFFunction function = new PDFFunction(++this.objectcount, + theFunctionType, theDomain, + theRange, theFunctions, + theBounds, theEncode); + + PDFFunction oldfunc = findFunction(function); + if (oldfunc == null) { + functions.add(function); + this.objects.add(function); + } else { + this.objectcount--; + function = oldfunc; + } + + return (function); + } + + /** + * make a postscript calculator function + * + * @param theNumber the PDF object number + * @param theFunctionType the type of function to make + * @param theDomain the domain values + * @param theRange the range values of the function + * @param theFunctionDataStream a string containing the pdf drawing + * @return the PDF function that was created + */ + public PDFFunction makeFunction(int theNumber, int theFunctionType, + List theDomain, List theRange, + StringBuffer theFunctionDataStream) { + // Type 4 + PDFFunction function = new PDFFunction(++this.objectcount, + theFunctionType, theDomain, + theRange, + theFunctionDataStream); + + PDFFunction oldfunc = findFunction(function); + if (oldfunc == null) { + functions.add(function); + this.objects.add(function); + } else { + this.objectcount--; + function = oldfunc; + } + + return (function); + + } + + /** + * make a function based shading object + * + * @param res the PDF resource context to add the shading, may be null + * @param theShadingType The type of shading object, which should be 1 for function + * based shading. + * @param theColorSpace The colorspace is 'DeviceRGB' or something similar. + * @param theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Whether or not to anti-alias. + * @param theDomain Optional vector of Doubles specifying the domain. + * @param theMatrix List of Doubles specifying the matrix. + * If it's a pattern, then the matrix maps it to pattern space. + * If it's a shading, then it maps it to current user space. + * It's optional, the default is the identity matrix + * @param theFunction The PDF Function that maps an (x,y) location to a color + * @return the PDF shading that was created + */ + public PDFShading makeShading(PDFResourceContext res, int theShadingType, + PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, List theDomain, + List theMatrix, + PDFFunction theFunction) { + // make Shading of Type 1 + String theShadingName = new String("Sh" + (++this.shadingCount)); + + PDFShading shading = new PDFShading(++this.objectcount, + theShadingName, theShadingType, + theColorSpace, theBackground, + theBBox, theAntiAlias, theDomain, + theMatrix, theFunction); + + PDFShading oldshad = findShading(shading); + if (oldshad == null) { + shadings.add(shading); + this.objects.add(shading); + } else { + this.objectcount--; + this.shadingCount--; + shading = oldshad; + } + + // add this shading to resources + if (res != null) { + res.getPDFResources().addShading(shading); + } else { + this.resources.addShading(shading); + } + + return (shading); + } + + /** + * Make an axial or radial shading object. + * + * @param res the PDF resource context to add the shading, may be null + * @param theShadingType 2 or 3 for axial or radial shading + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theCoords List of four (type 2) or 6 (type 3) Double + * @param theDomain List of Doubles specifying the domain + * @param theFunction the Stitching (PDFfunction type 3) function, + * even if it's stitching a single function + * @param theExtend List of Booleans of whether to extend the + * start and end colors past the start and end points + * The default is [false, false] + * @return the PDF shading that was created + */ + public PDFShading makeShading(PDFResourceContext res, int theShadingType, + PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, List theCoords, + List theDomain, PDFFunction theFunction, + List theExtend) { + // make Shading of Type 2 or 3 + String theShadingName = new String("Sh" + (++this.shadingCount)); + + PDFShading shading = new PDFShading(++this.objectcount, + theShadingName, theShadingType, + theColorSpace, theBackground, + theBBox, theAntiAlias, theCoords, + theDomain, theFunction, + theExtend); + + PDFShading oldshad = findShading(shading); + if (oldshad == null) { + shadings.add(shading); + this.objects.add(shading); + } else { + this.objectcount--; + this.shadingCount--; + shading = oldshad; + } + + if (res != null) { + res.getPDFResources().addShading(shading); + } else { + this.resources.addShading(shading); + } + + return (shading); + } + + /** + * Make a free-form gouraud shaded triangle mesh, coons patch mesh, or tensor patch mesh + * shading object + * + * @param res the PDF resource context to add the shading, may be null + * @param theShadingType 4, 6, or 7 depending on whether it's + * Free-form gouraud-shaded triangle meshes, coons patch meshes, + * or tensor product patch meshes, respectively. + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32. + * @param theBitsPerComponent 1,2,4,8,12, and 16 + * @param theBitsPerFlag 2,4,8. + * @param theDecode List of Doubles see PDF 1.3 spec pages 303 to 312. + * @param theFunction the PDFFunction + * @return the PDF shading that was created + */ + public PDFShading makeShading(PDFResourceContext res, int theShadingType, + PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, + int theBitsPerCoordinate, + int theBitsPerComponent, + int theBitsPerFlag, List theDecode, + PDFFunction theFunction) { + // make Shading of type 4,6 or 7 + String theShadingName = new String("Sh" + (++this.shadingCount)); + + PDFShading shading = new PDFShading(++this.objectcount, + theShadingName, theShadingType, + theColorSpace, theBackground, + theBBox, theAntiAlias, + theBitsPerCoordinate, + theBitsPerComponent, + theBitsPerFlag, theDecode, + theFunction); + + PDFShading oldshad = findShading(shading); + if (oldshad == null) { + shadings.add(shading); + this.objects.add(shading); + } else { + this.objectcount--; + this.shadingCount--; + shading = oldshad; + } + + if (res != null) { + res.getPDFResources().addShading(shading); + } else { + this.resources.addShading(shading); + } + + return (shading); + } + + /** + * make a Lattice-Form Gouraud mesh shading object + * + * @param res the PDF resource context to add the shading, may be null + * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh + * without spaces. "Shading1" or "Sh1" are good examples. + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32 + * @param theBitsPerComponent 1,2,4,8,12,24,32 + * @param theDecode List of Doubles. See page 305 in PDF 1.3 spec. + * @param theVerticesPerRow number of vertices in each "row" of the lattice. + * @param theFunction The PDFFunction that's mapped on to this shape + * @return the PDF shading that was created + */ + public PDFShading makeShading(PDFResourceContext res, int theShadingType, + PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, + int theBitsPerCoordinate, + int theBitsPerComponent, List theDecode, + int theVerticesPerRow, + PDFFunction theFunction) { + // make shading of Type 5 + String theShadingName = new String("Sh" + (++this.shadingCount)); + + PDFShading shading = new PDFShading(++this.objectcount, + theShadingName, theShadingType, + theColorSpace, theBackground, + theBBox, theAntiAlias, + theBitsPerCoordinate, + theBitsPerComponent, theDecode, + theVerticesPerRow, theFunction); + + PDFShading oldshad = findShading(shading); + if (oldshad == null) { + shadings.add(shading); + this.objects.add(shading); + } else { + this.objectcount--; + this.shadingCount--; + shading = oldshad; + } + + if (res != null) { + res.getPDFResources().addShading(shading); + } else { + this.resources.addShading(shading); + } + + return (shading); + } + + /** + * Make a tiling pattern + * + * @param res the PDF resource context to add the shading, may be null + * @param thePatternType the type of pattern, which is 1 for tiling. + * @param theResources the resources associated with this pattern + * @param thePaintType 1 or 2, colored or uncolored. + * @param theTilingType 1, 2, or 3, constant spacing, no distortion, or faster tiling + * @param theBBox List of Doubles: The pattern cell bounding box + * @param theXStep horizontal spacing + * @param theYStep vertical spacing + * @param theMatrix Optional List of Doubles transformation matrix + * @param theXUID Optional vector of Integers that uniquely identify the pattern + * @param thePatternDataStream The stream of pattern data to be tiled. + * @return the PDF pattern that was created + */ + public PDFPattern makePattern(PDFResourceContext res, int thePatternType, // 1 + PDFResources theResources, int thePaintType, int theTilingType, + List theBBox, double theXStep, + double theYStep, List theMatrix, + List theXUID, StringBuffer thePatternDataStream) { + String thePatternName = new String("Pa" + (++this.patternCount)); + // int theNumber, String thePatternName, + // PDFResources theResources + PDFPattern pattern = new PDFPattern(++this.objectcount, + thePatternName, theResources, 1, + thePaintType, theTilingType, + theBBox, theXStep, theYStep, + theMatrix, theXUID, + thePatternDataStream); + + PDFPattern oldpatt = findPattern(pattern); + if (oldpatt == null) { + patterns.add(pattern); + this.objects.add(pattern); + } else { + this.objectcount--; + this.patternCount--; + pattern = oldpatt; + } + + if (res != null) { + res.getPDFResources().addPattern(pattern); + } else { + this.resources.addPattern(pattern); + } + + return (pattern); + } + + /** + * Make a smooth shading pattern + * + * @param res the PDF resource context to add the shading, may be null + * @param thePatternType the type of the pattern, which is 2, smooth shading + * @param theShading the PDF Shading object that comprises this pattern + * @param theXUID optional:the extended unique Identifier if used. + * @param theExtGState optional: the extended graphics state, if used. + * @param theMatrix Optional:List of Doubles that specify the matrix. + * @return the PDF pattern that was created + */ + public PDFPattern makePattern(PDFResourceContext res, + int thePatternType, PDFShading theShading, + List theXUID, StringBuffer theExtGState, + List theMatrix) { + String thePatternName = new String("Pa" + (++this.patternCount)); + + PDFPattern pattern = new PDFPattern(++this.objectcount, + thePatternName, 2, theShading, + theXUID, theExtGState, theMatrix); + + PDFPattern oldpatt = findPattern(pattern); + if (oldpatt == null) { + patterns.add(pattern); + this.objects.add(pattern); + } else { + this.objectcount--; + this.patternCount--; + pattern = oldpatt; + } + + if (res != null) { + res.getPDFResources().addPattern(pattern); + } else { + this.resources.addPattern(pattern); + } + + return (pattern); + } + + /** + * Get the color space. + * + * @return the color space + */ + public int getColorSpace() { + return (this.colorspace.getColorSpace()); + } + + /** + * Set the color space. + * This is used when creating gradients. + * + * @param theColorspace the new color space + */ + public void setColorSpace(int theColorspace) { + this.colorspace.setColorSpace(theColorspace); + return; + } + + /** + * Make a gradient + * + * @param res the PDF resource context to add the shading, may be null + * @param radial if true a radial gradient will be created + * @param theColorspace the colorspace of the gradient + * @param theColors the list of colors for the gradient + * @param theBounds the list of bounds associated with the colors + * @param theCoords the coordinates for the gradient + * @return the PDF pattern that was created + */ + public PDFPattern createGradient(PDFResourceContext res, boolean radial, + PDFColorSpace theColorspace, + List theColors, List theBounds, + List theCoords) { + PDFShading myShad; + PDFFunction myfunky; + PDFFunction myfunc; + List theCzero; + List theCone; + PDFPattern myPattern; + //PDFColorSpace theColorSpace; + double interpolation = (double)1.000; + List theFunctions = new java.util.ArrayList(); + + int currentPosition; + int lastPosition = theColors.size() - 1; + + + // if 5 elements, the penultimate element is 3. + // do not go beyond that, because you always need + // to have a next color when creating the function. + + for (currentPosition = 0; currentPosition < lastPosition; + currentPosition++) { // for every consecutive color pair + PDFColor currentColor = + (PDFColor)theColors.get(currentPosition); + PDFColor nextColor = (PDFColor)theColors.get(currentPosition + + 1); + // colorspace must be consistant + if (this.colorspace.getColorSpace() + != currentColor.getColorSpace()) { + currentColor.setColorSpace(this.colorspace.getColorSpace()); + } + + if (this.colorspace.getColorSpace() != nextColor.getColorSpace()) { + nextColor.setColorSpace(this.colorspace.getColorSpace()); + } + + theCzero = currentColor.getVector(); + theCone = nextColor.getVector(); + + myfunc = this.makeFunction(2, null, null, theCzero, theCone, + interpolation); + + theFunctions.add(myfunc); + + } // end of for every consecutive color pair + + myfunky = this.makeFunction(3, null, null, theFunctions, theBounds, + null); + + if (radial) { + if (theCoords.size() == 6) { + myShad = this.makeShading(res, 3, this.colorspace, null, null, + false, theCoords, null, myfunky, + null); + } else { // if the center x, center y, and radius specifiy + // the gradient, then assume the same center x, center y, + // and radius of zero for the other necessary component + List newCoords = new java.util.ArrayList(); + newCoords.add(theCoords.get(0)); + newCoords.add(theCoords.get(1)); + newCoords.add(theCoords.get(2)); + newCoords.add(theCoords.get(0)); + newCoords.add(theCoords.get(1)); + newCoords.add(new Double(0.0)); + + myShad = this.makeShading(res, 3, this.colorspace, null, null, + false, newCoords, null, myfunky, + null); + + } + } else { + myShad = this.makeShading(res, 2, this.colorspace, null, null, false, + theCoords, null, myfunky, null); + + } + + myPattern = this.makePattern(res, 2, myShad, null, null, null); + + return (myPattern); + } + + + /** + * make a /Encoding object + * + * @param encodingName character encoding scheme name + * @return the created /Encoding object + */ + public PDFEncoding makeEncoding(String encodingName) { + + /* + * create a PDFEncoding with the next object number and add to the + * list of objects + */ + PDFEncoding encoding = new PDFEncoding(++this.objectcount, + encodingName); + this.objects.add(encoding); + return encoding; + } + + /** + * Create a PDFICCStream + * @see PDFXObject + * @see org.apache.fop.image.JpegImage + * @see org.apache.fop.pdf.PDFColorSpace + * @return the new PDF ICC stream object + */ + public PDFICCStream makePDFICCStream() { + PDFICCStream iccStream = new PDFICCStream(++this.objectcount); + this.objects.add(iccStream); + return iccStream; + } + + /** + * Get the font map for this document. + * + * @return the map of fonts used in this document + */ + public Map getFontMap() { + return fontMap; + } + + /** + * make a Type1 /Font object + * + * @param fontname internal name to use for this font (eg "F1") + * @param basefont name of the base font (eg "Helvetica") + * @param encoding character encoding scheme used by the font + * @param metrics additional information about the font + * @param descriptor additional information about the font + * @return the created /Font object + */ + public PDFFont makeFont(String fontname, String basefont, + String encoding, FontMetrics metrics, + FontDescriptor descriptor) { + if (fontMap.containsKey(fontname)) { + return (PDFFont)fontMap.get(fontname); + } + + /* + * create a PDFFont with the next object number and add to the + * list of objects + */ + if (descriptor == null) { + PDFFont font = new PDFFont(++this.objectcount, fontname, + FontType.TYPE1, basefont, encoding); + this.objects.add(font); + fontMap.put(fontname, font); + return font; + } else { + FontType fonttype = metrics.getFontType(); + + PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor); + + PDFFontNonBase14 font = null; + if (fonttype == FontType.TYPE0) { + /* + * Temporary commented out - customized CMaps + * isn't needed until /ToUnicode support is added + * PDFCMap cmap = new PDFCMap(++this.objectcount, + * "fop-ucs-H", + * new PDFCIDSystemInfo("Adobe", + * "Identity", + * 0)); + * cmap.addContents(); + * this.objects.add(cmap); + */ + font = + (PDFFontNonBase14)PDFFont.createFont(++this.objectcount, + fontname, fonttype, + basefont, + "Identity-H"); + } else { + + font = + (PDFFontNonBase14)PDFFont.createFont(++this.objectcount, + fontname, fonttype, + basefont, encoding); + } + this.objects.add(font); + + font.setDescriptor(pdfdesc); + + if (fonttype == FontType.TYPE0) { + CIDFont cidMetrics; + if (metrics instanceof LazyFont) { + cidMetrics = (CIDFont)((LazyFont) metrics).getRealFont(); + } else { + cidMetrics = (CIDFont)metrics; + } + PDFCIDSystemInfo sysInfo = + new PDFCIDSystemInfo(cidMetrics.getRegistry(), + cidMetrics.getOrdering(), + cidMetrics.getSupplement()); + PDFCIDFont cidFont = + new PDFCIDFont(++this.objectcount, basefont, + cidMetrics.getCIDType(), + cidMetrics.getDefaultWidth(), + cidMetrics.getWidths(), sysInfo, + (PDFCIDFontDescriptor)pdfdesc); + this.objects.add(cidFont); + + ((PDFFontType0)font).setDescendantFonts(cidFont); + } else { + int firstChar = 0; + int lastChar = 255; + if (metrics instanceof CustomFont) { + CustomFont cf = (CustomFont)metrics; + firstChar = cf.getFirstChar(); + lastChar = cf.getLastChar(); + } + font.setWidthMetrics(firstChar, + lastChar, + makeArray(metrics.getWidths())); + } + + fontMap.put(fontname, font); + + return font; + } + } + + + /** + * make a /FontDescriptor object + * + * @param desc the font descriptor + * @return the new PDF font descriptor + */ + public PDFFontDescriptor makeFontDescriptor(FontDescriptor desc) { + PDFFontDescriptor font = null; + + if (desc.getFontType() == FontType.TYPE0) { + // CID Font + font = new PDFCIDFontDescriptor(++this.objectcount, + desc.getFontName(), + desc.getFontBBox(), + desc.getCapHeight(), desc.getFlags(), + desc.getItalicAngle(), + desc.getStemV(), null); + } else { + // Create normal FontDescriptor + font = new PDFFontDescriptor(++this.objectcount, desc.getFontName(), + desc.getAscender(), + desc.getDescender(), + desc.getCapHeight(), + desc.getFlags(), + new PDFRectangle(desc.getFontBBox()), + desc.getStemV(), + desc.getItalicAngle()); + } + this.objects.add(font); + + // Check if the font is embeddable + if (desc.isEmbeddable()) { + PDFStream stream = makeFontFile(this.objectcount + 1, desc); + if (stream != null) { + this.objectcount++; + font.setFontFile(desc.getFontType(), stream); + this.objects.add(stream); + } + } + return font; + } + + /** + * Resolve a URI. + * + * @param uri the uri to resolve + * @throws java.io.FileNotFoundException if the URI could not be resolved + * @return the InputStream from the URI. + */ + protected InputStream resolveURI(String uri) + throws java.io.FileNotFoundException { + try { + /**@todo Temporary hack to compile, improve later */ + return new java.net.URL(uri).openStream(); + } catch (Exception e) { + throw new java.io.FileNotFoundException( + "URI could not be resolved (" + e.getMessage() + "): " + uri); + } + } + + /** + * Embeds a font. + * @param obj PDF object number to use + * @param desc FontDescriptor of the font. + * @return PDFStream The embedded font file + */ + public PDFStream makeFontFile(int obj, FontDescriptor desc) { + if (desc.getFontType() == FontType.OTHER) { + throw new IllegalArgumentException("Trying to embed unsupported font type: " + + desc.getFontType()); + } + if (!(desc instanceof CustomFont)) { + throw new IllegalArgumentException( + "FontDescriptor must be instance of CustomFont, but is a " + + desc.getClass().getName()); + } + + CustomFont font = (CustomFont)desc; + + InputStream in = null; + try { + // Get file first + if (font.getEmbedFileName() != null) { + try { + in = resolveURI(font.getEmbedFileName()); + } catch (Exception e) { + System.out.println("Failed to embed fontfile: " + + font.getEmbedFileName()); + } + } + + // Get resource + if (in == null && font.getEmbedResourceName() != null) { + try { + in = new java.io.BufferedInputStream( + this.getClass().getResourceAsStream(font.getEmbedResourceName())); + } catch (Exception e) { + System.out.println("Failed to embed fontresource: " + + font.getEmbedResourceName()); + } + } + + if (in == null) { + return null; + } else { + try { + PDFStream embeddedFont; + if (desc.getFontType() == FontType.TYPE0) { + MultiByteFont mbfont = (MultiByteFont)font; + FontFileReader reader = new FontFileReader(in); + + TTFSubSetFile subset = new TTFSubSetFile(); + + byte[] subsetFont = subset.readFont(reader, + mbfont.getTTCName(), mbfont.getUsedGlyphs()); + // Only TrueType CID fonts are supported now + + embeddedFont = new PDFTTFStream(obj, subsetFont.length); + ((PDFTTFStream)embeddedFont).setData(subsetFont, subsetFont.length); + } else if (desc.getFontType() == FontType.TYPE1) { + PFBParser parser = new PFBParser(); + PFBData pfb = parser.parsePFB(in); + embeddedFont = new PDFT1Stream(obj); + ((PDFT1Stream)embeddedFont).setData(pfb); + } else { + byte[] file = StreamUtilities.toByteArray(in, 128000); + embeddedFont = new PDFTTFStream(obj, file.length); + ((PDFTTFStream)embeddedFont).setData(file, file.length); + } + embeddedFont.addFilter("flate"); + embeddedFont.addFilter("ascii-85"); + return embeddedFont; + } finally { + in.close(); + } + } + } catch (IOException ioe) { + //log.error("Failed to embed font [" + obj + "] " + // + fontName + ": " + ioe.getMessage()); + return (PDFStream) null; + } + } + +/* + public PDFStream getFontFile(int i) { + PDFStream embeddedFont = null; + + + return (PDFStream)embeddedFont; + } + + + public PDFStream getFontFile(int i) { + } + +*/ + + + /** + * make an Array object (ex. Widths array for a font) + * + * @param values the int array values + * @return the PDF Array with the int values + */ + public PDFArray makeArray(int[] values) { + PDFArray array = new PDFArray(++this.objectcount, values); + this.objects.add(array); + return array; + } + + /** + * make an ExtGState for extra graphics options + * This tries to find a GState that will setup the correct values + * for the current context. If there is no suitable GState it will + * create a new one. + * + * @param settings the settings required by the caller + * @param current the current GState of the current PDF context + * @return a PDF GState, either an existing GState or a new one + */ + public PDFGState makeGState(Map settings, PDFGState current) { + + // try to locate a gstate that has all the settings + // or will inherit from the current gstate + // compare "DEFAULT + settings" with "current + each gstate" + + PDFGState wanted = new PDFGState(0); + wanted.addValues(PDFGState.DEFAULT); + wanted.addValues(settings); + + PDFGState poss; + for (Iterator iter = gstates.iterator(); iter.hasNext();) { + PDFGState avail = (PDFGState)iter.next(); + poss = new PDFGState(0); + poss.addValues(current); + poss.addValues(avail); + if (poss.equals(wanted)) { + return avail; + } + } + + PDFGState gstate = new PDFGState(++this.objectcount); + gstate.addValues(settings); + this.objects.add(gstate); + gstates.add(gstate); + return gstate; + } + + /** + * Get an image from the image map. + * + * @param key the image key to look for + * @return the image or PDFXObject for the key if found + */ + public PDFXObject getImage(String key) { + PDFXObject xObject = (PDFXObject)xObjectsMap.get(key); + return xObject; + } + + /** + * Add an image to the PDF document. + * This adds an image to the PDF objects. + * If an image with the same key already exists it will return the + * old PDFXObject. + * + * @param res the PDF resource context to add to, may be null + * @param img the PDF image to add + * @return the PDF XObject that references the PDF image data + */ + public PDFXObject addImage(PDFResourceContext res, PDFImage img) { + // check if already created + String key = img.getKey(); + PDFXObject xObject = (PDFXObject)xObjectsMap.get(key); + if (xObject != null) { + if (res != null) { + res.getPDFResources().addXObject(xObject); + } + return xObject; + } + + // setup image + img.setup(this); + // create a new XObject + xObject = new PDFXObject(++this.objectcount, ++this.xObjectCount, + img); + this.objects.add(xObject); + this.resources.addXObject(xObject); + if (res != null) { + res.getPDFResources().addXObject(xObject); + } + this.xObjectsMap.put(key, xObject); + return xObject; + } + + /** + * Add a form XObject to the PDF document. + * This adds a Form XObject to the PDF objects. + * If a Form XObject with the same key already exists it will return the + * old PDFFormXObject. + * + * @param res the PDF resource context to add to, may be null + * @param cont the PDF Stream contents of the Form XObject + * @param formres the PDF Resources for the Form XObject data + * @param key the key for the object + * @return the PDF Form XObject that references the PDF data + */ + public PDFFormXObject addFormXObject(PDFResourceContext res, PDFStream cont, + PDFResources formres, String key) { + PDFFormXObject xObject; + xObject = new PDFFormXObject(++this.objectcount, ++this.xObjectCount, + cont, formres.referencePDF()); + this.objects.add(xObject); + this.resources.addXObject(xObject); + if (res != null) { + res.getPDFResources().addXObject(xObject); + } + return xObject; + } + + /** + * make a /Page object + * + * @param resources resources object to use + * @param pagewidth width of the page in points + * @param pageheight height of the page in points + * + * @return the created /Page object + */ + public PDFPage makePage(PDFResources resources, + int pagewidth, int pageheight) { + + /* + * create a PDFPage with the next object number, the given + * resources, contents and dimensions + */ + PDFPage page = new PDFPage(this, ++this.objectcount, resources, + pagewidth, pageheight); + + /* add it to the list of objects */ + pages.addPage(page); + return page; + } + + /** + * Add a completed page to the PDF document. + * The page is added to the object list. + * + * @param page the page to add + */ + public void addPage(PDFPage page) { + /* add it to the list of objects */ + this.objects.add(page); + } + + private PDFLink findLink(PDFLink compare) { + return (PDFLink)findPDFObject(links, compare); + } + + private PDFFileSpec findFileSpec(PDFFileSpec compare) { + return (PDFFileSpec)findPDFObject(filespecs, compare); + } + + private PDFGoToRemote findGoToRemote(PDFGoToRemote compare) { + return (PDFGoToRemote)findPDFObject(gotoremotes, compare); + } + + private PDFGoTo findGoTo(PDFGoTo compare) { + return (PDFGoTo)findPDFObject(gotos, compare); + } + + /** + * make a link object + * + * @param rect the clickable rectangle + * @param destination the destination file + * @param linkType the link type + * @param yoffset the yoffset on the page for an internal link + * @return the PDFLink object created + */ + public PDFLink makeLink(Rectangle2D rect, String destination, + int linkType, float yoffset) { + + //PDFLink linkObject; + int index; + + PDFLink link = new PDFLink(++this.objectcount, rect); + + if (linkType == PDFLink.EXTERNAL) { + // check destination + if (destination.startsWith("http://")) { + PDFUri uri = new PDFUri(destination); + link.setAction(uri); + } else if (destination.endsWith(".pdf")) { // FileSpec + PDFGoToRemote remote = getGoToPDFAction(destination, null, -1); + link.setAction(remote); + } else if ((index = destination.indexOf(".pdf#page=")) > 0) { + //String file = destination.substring(0, index + 4); + int page = Integer.parseInt(destination.substring(index + 10)); + PDFGoToRemote remote = getGoToPDFAction(destination, null, page); + link.setAction(remote); + } else if ((index = destination.indexOf(".pdf#dest=")) > 0) { + //String file = destination.substring(0, index + 4); + String dest = destination.substring(index + 10); + PDFGoToRemote remote = getGoToPDFAction(destination, dest, -1); + link.setAction(remote); + } else { // URI + PDFUri uri = new PDFUri(destination); + link.setAction(uri); + } + } else { + // linkType is internal + String goToReference = getGoToReference(destination, yoffset); + PDFInternalLink internalLink = new PDFInternalLink(goToReference); + link.setAction(internalLink); + } + + PDFLink oldlink = findLink(link); + if (oldlink == null) { + links.add(link); + this.objects.add(link); + } else { + this.objectcount--; + link = oldlink; + } + + return link; + } + + /** + * Create and return a goto pdf document action. + * This creates a pdf files spec and pdf goto remote action. + * It also checks available pdf objects so it will not create an + * object if it already exists. + * + * @param file the pdf file name + * @param dest the remote name destination, may be null + * @param page the remote page number, -1 means not specified + * @return the pdf goto remote object + */ + private PDFGoToRemote getGoToPDFAction(String file, String dest, int page) { + PDFFileSpec fileSpec = new PDFFileSpec(++this.objectcount, file); + PDFFileSpec oldspec = findFileSpec(fileSpec); + if (oldspec == null) { + filespecs.add(fileSpec); + this.objects.add(fileSpec); + } else { + this.objectcount--; + fileSpec = oldspec; + } + PDFGoToRemote remote; + + if (dest == null && page == -1) { + remote = new PDFGoToRemote(++this.objectcount, fileSpec); + } else if (dest != null) { + remote = new PDFGoToRemote(++this.objectcount, fileSpec, dest); + } else { + remote = new PDFGoToRemote(++this.objectcount, fileSpec, page); + } + PDFGoToRemote oldremote = findGoToRemote(remote); + if (oldremote == null) { + gotoremotes.add(remote); + this.objects.add(remote); + } else { + this.objectcount--; + remote = oldremote; + } + return remote; + } + + private String getGoToReference(String destination, float yoffset) { + String goToReference = null; + PDFGoTo gt = new PDFGoTo(++this.objectcount, destination); + gt.setYPosition(yoffset); + PDFGoTo oldgt = findGoTo(gt); + if (oldgt == null) { + gotos.add(gt); + addTrailerObject(gt); + } else { + this.objectcount--; + gt = oldgt; + } + + goToReference = gt.referencePDF(); + return goToReference; + } + + /** + * Add trailer object. + * Adds an object to the list of trailer objects. + * + * @param object the PDF object to add + */ + public void addTrailerObject(PDFObject object) { + this.trailerObjects.add(object); + } + + /** + * Make an internal link. + * + * @param rect the hotspot position in absolute coordinates + * @param page the target page reference value + * @param dest the position destination + * @return the new PDF link object + */ + public PDFLink makeLink(Rectangle2D rect, String page, String dest) { + PDFLink link = new PDFLink(++this.objectcount, rect); + this.objects.add(link); + + PDFGoTo gt = new PDFGoTo(++this.objectcount, page); + gt.setDestination(dest); + addTrailerObject(gt); + PDFInternalLink internalLink = new PDFInternalLink(gt.referencePDF()); + link.setAction(internalLink); + + return link; + } + + /** + * Ensure there is room in the locations xref for the number of + * objects that have been created. + */ + private void prepareLocations() { + while (location.size() < objectcount) { + location.add(LOCATION_PLACEHOLDER); + } + } + + /** + * make a stream object + * + * @param type the type of stream to be created + * @param add if true then the stream will be added immediately + * @return the stream object created + */ + public PDFStream makeStream(String type, boolean add) { + + /* + * create a PDFStream with the next object number and add it + * + * to the list of objects + */ + PDFStream obj = new PDFStream(++this.objectcount); + obj.addDefaultFilters(filterMap, type); + + if (add) { + this.objects.add(obj); + } + return obj; + } + + /** + * add a stream object + * + * @param obj the PDF Stream to add to this document + */ + public void addStream(PDFStream obj) { + this.objects.add(obj); + } + + /** + * make an annotation list object + * + * @return the annotation list object created + */ + public PDFAnnotList makeAnnotList() { + + /* + * create a PDFAnnotList with the next object number and add it + * to the list of objects + */ + PDFAnnotList obj = new PDFAnnotList(++this.objectcount); + return obj; + } + + /** + * Add an annotation list object to the pdf document + * + * @param obj the annotation list to add + */ + public void addAnnotList(PDFAnnotList obj) { + this.objects.add(obj); + } + + /** + * Get the root Outlines object. This method does not write + * the outline to the PDF document, it simply creates a + * reference for later. + * + * @return the PDF Outline root object + */ + public PDFOutline getOutlineRoot() { + if (outlineRoot != null) { + return outlineRoot; + } + + outlineRoot = new PDFOutline(++this.objectcount, null, null); + addTrailerObject(outlineRoot); + root.setRootOutline(outlineRoot); + return outlineRoot; + } + + /** + * Make an outline object and add it to the given outline + * + * @param parent parent PDFOutline object which may be null + * @param label the title for the new outline object + * @param destination the reference string for the action to go to + * @param yoffset the yoffset on the destination page + * @return the new PDF outline object + */ + public PDFOutline makeOutline(PDFOutline parent, String label, + String destination, float yoffset) { + String goToRef = getGoToReference(destination, yoffset); + + PDFOutline obj = new PDFOutline(++this.objectcount, label, goToRef); + + if (parent != null) { + parent.addOutline(obj); + } + this.objects.add(obj); + return obj; + } + + /** + * get the /Resources object for the document + * + * @return the /Resources object + */ + public PDFResources getResources() { + return this.resources; + } + + /** + * write the entire document out + * + * @param stream the OutputStream to output the document to + * @throws IOException if there is an exception writing to the output stream + */ + public void output(OutputStream stream) throws IOException { + + prepareLocations(); + + for (int count = 0; count < this.objects.size(); count++) { + /* retrieve the object with the current number */ + PDFObject object = (PDFObject)this.objects.get(count); + + /* + * add the position of this object to the list of object + * locations + */ + location.set(object.getNumber() - 1, + new Integer(this.position)); + + /* + * output the object and increment the character position + * by the object's length + */ + this.position += object.output(stream); + } + + this.objects.clear(); + } + + /** + * write the PDF header

+ * + * This method must be called prior to formatting + * and outputting AreaTrees. + * + * @param stream the OutputStream to write the header to + * @throws IOException if there is an exception writing to the output stream + */ + public void outputHeader(OutputStream stream) + throws IOException { + this.position = 0; + + byte[] pdf = ("%PDF-" + PDF_VERSION + "\n").getBytes(); + stream.write(pdf); + this.position += pdf.length; + + // output a binary comment as recommended by the PDF spec (3.4.1) + byte[] bin = { + (byte)'%', (byte)0xAA, (byte)0xAB, (byte)0xAC, (byte)0xAD, + (byte)'\n' + }; + stream.write(bin); + this.position += bin.length; + } + + /** + * write the trailer + * + * @param stream the OutputStream to write the trailer to + * @throws IOException if there is an exception writing to the output stream + */ + public void outputTrailer(OutputStream stream) + throws IOException { + output(stream); + for (int count = 0; count < trailerObjects.size(); count++) { + PDFObject o = (PDFObject) trailerObjects.get(count); + this.location.set(o.getNumber() - 1, + new Integer(this.position)); + this.position += o.output(stream); + } + /* output the xref table and increment the character position + by the table's length */ + this.position += outputXref(stream); + + /* construct the trailer */ + String pdf = "trailer\n" + "<<\n" + + "/Size " + (this.objectcount + 1) + "\n" + + "/Root " + this.root.number + " " + + this.root.generation + " R\n" + "/Info " + + this.info.number + " " + this.info.generation + + " R\n" + ">>\n" + "startxref\n" + this.xref + + "\n" + "%%EOF\n"; + + /* write the trailer */ + stream.write(pdf.getBytes()); + } + + /** + * write the xref table + * + * @param stream the OutputStream to write the xref table to + * @return the number of characters written + */ + private int outputXref(OutputStream stream) throws IOException { + + /* remember position of xref table */ + this.xref = this.position; + + /* construct initial part of xref */ + StringBuffer pdf = new StringBuffer("xref\n0 " + + (this.objectcount + 1) + + "\n0000000000 65535 f \n"); + + for (int count = 0; count < this.location.size(); count++) { + String x = this.location.get(count).toString(); + + /* contruct xref entry for object */ + String padding = "0000000000"; + String loc = padding.substring(x.length()) + x; + + /* append to xref table */ + pdf = pdf.append(loc + " 00000 n \n"); + } + + /* write the xref table and return the character length */ + byte[] pdfBytes = pdf.toString().getBytes(); + stream.write(pdfBytes); + return pdfBytes.length; + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFEncoding.java b/src/java/org/apache/fop/pdf/PDFEncoding.java new file mode 100644 index 000000000..b048cd2db --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFEncoding.java @@ -0,0 +1,167 @@ +/* + * $Id: PDFEncoding.java,v 1.6 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.util.List; +import java.util.Map; +import java.util.Iterator; +import java.util.HashMap; + +/** + * class representing an /Encoding object. + * + * A small object expressing the base encoding name and + * the differences from the base encoding. + * + * The three base encodings are given by their name. + * + * Encodings are specified in section 5.5.5 of the PDF 1.4 spec. + */ +public class PDFEncoding extends PDFObject { + + /** + * the name for the standard encoding scheme + */ + public static final String MAC_ROMAN_ENCODING = "MacRomanEncoding"; + + /** + * the name for the standard encoding scheme + */ + public static final String MAC_EXPERT_ENCODING = "MacExpertEncoding"; + + /** + * the name for the standard encoding scheme + */ + public static final String WIN_ANSI_ENCODING = "WinAnsiEncoding"; + + /** + * the name for the base encoding. + * One of the three base encoding scheme names or + * the default font's base encoding if null. + */ + protected String basename; + + /** + * the differences from the base encoding + */ + protected Map differences; + + /** + * create the /Encoding object + * + * @param number the object's number + * @param basename the name of the character encoding schema + */ + public PDFEncoding(int number, String basename) { + + /* generic creation of PDF object */ + super(number); + + /* set fields using paramaters */ + this.basename = basename; + this.differences = new HashMap(); + } + + /** + * add differences to the encoding + * + * @param code the first index of the sequence to be changed + * @param sequence the sequence of glyph names (as String) + */ + public void addDifferences(int code, List sequence) { + differences.put(new Integer(code), sequence); + } + + /** + * produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + + " obj\n<< /Type /Encoding"); + if ((basename != null) && (!basename.equals(""))) { + p.append("\n/BaseEncoding /" + this.basename); + } + if (!differences.isEmpty()) { + p.append("\n/Differences [ "); + Object code; + Iterator codes = differences.keySet().iterator(); + while (codes.hasNext()) { + code = codes.next(); + p.append(" "); + p.append(code); + List sequence = (List)differences.get(code); + for (int i = 0; i < sequence.size(); i++) { + p.append(" /"); + p.append((String)sequence.get(i)); + } + } + p.append(" ]"); + } + p.append(" >>\nendobj\n"); + return p.toString().getBytes(); + } + + /* + * example (p. 214) + * 25 0 obj + * << + * /Type /Encoding + * /Differences [39 /quotesingle 96 /grave 128 + * /Adieresis /Aring /Ccedilla /Eacute /Ntilde + * /Odieresis /Udieresis /aacute /agrave] + * >> + * endobj + */ +} diff --git a/src/java/org/apache/fop/pdf/PDFFileSpec.java b/src/java/org/apache/fop/pdf/PDFFileSpec.java new file mode 100644 index 000000000..b21e45368 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFileSpec.java @@ -0,0 +1,124 @@ +/* + * $Id: PDFFileSpec.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a /FileSpec object. + * + */ +public class PDFFileSpec extends PDFObject { + + /** + * the filename + */ + protected String filename; + + /** + * create a /FileSpec object. + * + * @param number the object's number + * @param filename the filename represented by this object + */ + public PDFFileSpec(int number, String filename) { + + /* generic creation of object */ + super(number); + + this.filename = filename; + } + + /** + * represent the object in PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + String p = new String(this.number + " " + this.generation + + " obj\n<<\n/Type /FileSpec\n" + "/F (" + + this.filename + ")\n" + ">>\nendobj\n"); + return p.getBytes(); + } + + /* + * example + * 29 0 obj + * << + * /Type /FileSpec + * /F (table1.pdf) + * >> + * endobj + */ + + /** + * Check if this equals another object. + * + * @param obj the object to compare + * @return true if this equals other object + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || !(obj instanceof PDFFileSpec)) { + return false; + } + + PDFFileSpec spec = (PDFFileSpec)obj; + + if (!spec.filename.equals(filename)) { + return false; + } + + return true; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFFilter.java b/src/java/org/apache/fop/pdf/PDFFilter.java new file mode 100644 index 000000000..9dba287bb --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFilter.java @@ -0,0 +1,130 @@ +/* + * $Id: PDFFilter.java,v 1.6 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * PDF Filter class. + * This represents a PDF filter object. + * Filter implementations should extend this class. + * + * @author Eric SCHAEFFER, Kelly A. Campbell + */ +public abstract class PDFFilter { + /* + * These are no longer needed, but are here as a reminder about what + * filters pdf supports. + * public static final int ASCII_HEX_DECODE = 1; + * public static final int ASCII_85_DECODE = 2; + * public static final int LZW_DECODE = 3; + * public static final int RUN_LENGTH_DECODE = 4; + * public static final int CCITT_FAX_DECODE = 5; + * public static final int DCT_DECODE = 6; + * public static final int FLATE_DECODE = 7; + */ + + /** + * Marker to know if this filter has already been applied to the data + */ + private boolean applied = false; + + /** + * Check if this filter has been applied. + * + * @return true if this filter has been applied + */ + public boolean isApplied() { + return applied; + } + + /** + * Set the applied attribute to the given value. This attribute is + * used to determine if this filter is just a placeholder for the + * decodeparms and dictionary entries, or if the filter needs to + * actually encode the data. For example if the raw data is copied + * out of an image file in it's compressed format, then this + * should be set to true and the filter options should be set to + * those which the raw data was encoded with. + * + * @param b set the applied value to this + */ + public void setApplied(boolean b) { + applied = b; + } + + /** + * return a PDF string representation of the filter, e.g. /FlateDecode + * + * @return the filter PDF name + */ + public abstract String getName(); + + /** + * return a parameter dictionary for this filter, or null + * + * @return the decode params for the filter + */ + public abstract String getDecodeParms(); + + /** + * encode the given data with the filter + * + * @param in the input data stream to encode + * @param out the output stream to write the result + * @param length the length of data to read from the input stream + * @throws IOException if there is an error reading or writing the data + */ + public abstract void encode(InputStream in, OutputStream out, int length) throws IOException; + +} diff --git a/src/java/org/apache/fop/pdf/PDFFilterException.java b/src/java/org/apache/fop/pdf/PDFFilterException.java new file mode 100644 index 000000000..2ee6c027a --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFilterException.java @@ -0,0 +1,75 @@ +/* + * $Id: PDFFilterException.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * PDF Filter exception. + * This is used for exceptions relating to use a PDF filter. + * + * @author Eric SCHAEFFER + */ +public class PDFFilterException extends Exception { + /** + * Create a basic filter exception. + */ + public PDFFilterException() { + } + + /** + * Create a filter exception with a message. + * + * @param message the error message + */ + public PDFFilterException(String message) { + super(message); + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFFont.java b/src/java/org/apache/fop/pdf/PDFFont.java new file mode 100644 index 000000000..7082ace31 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFont.java @@ -0,0 +1,264 @@ +/* + * $Id: PDFFont.java,v 1.12 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a /Font object. + *

+ * A more complete object expressing the base font name and encoding of a + * font along with an internal name for the font used within + * streams of content. + *

+ * Fonts are specified on page 198 and onwards of the PDF 1.3 spec. + */ +public class PDFFont extends PDFObject { + + /** + * the internal name for the font (eg "F1") + */ + protected String fontname; + + /** + * the font's subtype + * (as defined by the constants FontType: TYPE0, TYPE1, MMTYPE1, TYPE3, TRUETYPE) + */ + protected FontType subtype; + + /** + * the base font name (eg "Helvetica") + */ + protected String basefont; + + /** + * the character encoding scheme used by the font. + * It can be a String for standard encodings, or + * a PDFEncoding for a more complex scheme, or + * a PDFStream containing a CMap in a Type0 font. + * If null then not written out in the PDF. + */ + protected Object encoding; + + /** + * the Unicode mapping mechanism + */ + // protected PDFToUnicode mapping; + + /** + * create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param subtype the font's subtype + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFont(int number, String fontname, FontType subtype, + String basefont, + Object encoding /* , PDFToUnicode mapping */) { + + /* generic creation of PDF object */ + super(number); + + /* set fields using paramaters */ + this.fontname = fontname; + this.subtype = subtype; + this.basefont = basefont; + this.encoding = encoding; + // this.mapping = mapping; + } + + /** + * factory method with the basic parameters + * + * @param number the object's number + * @param fontname the internal name for the font + * @param subtype the font's subtype + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + * @return the generated PDFFont object + */ + public static PDFFont createFont(int number, String fontname, + FontType subtype, String basefont, + Object encoding) { + if (subtype == FontType.TYPE0) { + return new PDFFontType0(number, fontname, basefont, + encoding); + } else if ((subtype == FontType.TYPE1) + || (subtype == FontType.MMTYPE1)) { + return new PDFFontType1(number, fontname, basefont, + encoding); + } else if (subtype == FontType.TYPE3) { + //return new PDFFontType3(number, fontname, basefont, encoding); + return null; //NYI + } else if (subtype == FontType.TRUETYPE) { + return new PDFFontTrueType(number, fontname, basefont, + encoding); + } else { + return null; // should not happend + } + } + + /** + * factory method with the extended parameters + * for Type1, MMType1 and TrueType + * + * @param number the object's number + * @param fontname the internal name for the font + * @param subtype the font's subtype + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + * @param firstChar the first character code in the font + * @param lastChar the last character code in the font + * @param widths an array of size (lastChar - firstChar +1) + * @param descriptor the descriptor for other font's metrics + * @return the generated PDFFont object + */ + public static PDFFont createFont(int number, String fontname, + FontType subtype, String basefont, + Object encoding, int firstChar, + int lastChar, PDFArray widths, + PDFFontDescriptor descriptor) { + + PDFFontNonBase14 font; + if (subtype == FontType.TYPE0) { + font = new PDFFontType0(number, fontname, basefont, + encoding); + font.setDescriptor(descriptor); + return font; + } else if ((subtype == FontType.TYPE1) + || (subtype == FontType.MMTYPE1)) { + font = new PDFFontType1(number, fontname, basefont, + encoding); + font.setWidthMetrics(firstChar, lastChar, widths); + font.setDescriptor(descriptor); + return font; + } else if (subtype == FontType.TYPE3) { + return null; //NYI, should not happend + } else if (subtype == FontType.TRUETYPE) { + font = new PDFFontTrueType(number, fontname, basefont, + encoding); + font.setWidthMetrics(firstChar, lastChar, widths); + font.setDescriptor(descriptor); + return font; + } else { + return null; // should not happend + } + } + + /** + * get the internal name used for this font + * @return the internal name + */ + public String getName() { + return this.fontname; + } + + /** + * Returns the PDF name for a certain font type. + * @param fontType font type + * @return String corresponding PDF name + */ + protected String getPDFNameForFontType(FontType fontType) { + if (fontType == FontType.TYPE0) { + return fontType.getName(); + } else if (fontType == FontType.TYPE1) { + return fontType.getName(); + } else if (fontType == FontType.MMTYPE1) { + return fontType.getName(); + } else if (fontType == FontType.TYPE3) { + return fontType.getName(); + } else if (fontType == FontType.TRUETYPE) { + return fontType.getName(); + } else { + throw new IllegalArgumentException("Unsupported font type: " + fontType.getName()); + } + } + + /** + * Produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + + " obj\n<< /Type /Font\n/Subtype /" + + getPDFNameForFontType(this.subtype) + "\n/Name /" + this.fontname + + "\n/BaseFont /" + this.basefont); + if (encoding != null) { + p.append("\n/Encoding "); + if (encoding instanceof PDFEncoding) { + p.append(((PDFEncoding)this.encoding).referencePDF()); + } else if (encoding instanceof PDFStream) { + p.append(((PDFStream)this.encoding).referencePDF()); + } else { + p.append("/").append((String)encoding); + } + } + fillInPDF(p); + p.append(" >>\nendobj\n"); + return p.toString().getBytes(); + } + + /** + * This method is called to receive the specifics for the font's subtype. + *

+ * The given buffer already contains the fields common to all font types. + * + * @param target the buffer to be completed with the type specific fields + */ + protected void fillInPDF(StringBuffer target) { + //nop + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontDescriptor.java b/src/java/org/apache/fop/pdf/PDFFontDescriptor.java new file mode 100644 index 000000000..c605aaf8a --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontDescriptor.java @@ -0,0 +1,227 @@ +/* + * $Id: PDFFontDescriptor.java,v 1.7 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a font descriptor (/FontDescriptor object). + *

+ * Font descriptors are specified on page 222 and onwards of the PDF 1.3 spec. + */ +public class PDFFontDescriptor extends PDFObject { + + // Required fields + private int ascent; + private int capHeight; + private int descent; + private int flags; + private PDFRectangle fontBBox; + private String basefont; // PDF-spec: FontName + private int italicAngle; + private int stemV; + // Optional fields + private int stemH = 0; + private int xHeight = 0; + private int leading = 0; + private int avgWidth = 0; + private int maxWidth = 0; + private int missingWidth = 0; + private PDFStream fontfile; + // private String charSet = null; + + private FontType subtype; + + /** + * Create the /FontDescriptor object + * + * @param number the object's number + * @param ascent the maximum height above the baseline + * @param descent the maximum depth below the baseline + * @param capHeight height of the capital letters + * @param flags various characteristics of the font + * @param fontBBox the bounding box for the described font + * @param basefont the base font name + * @param italicAngle the angle of the vertical dominant strokes + * @param stemV the width of the dominant vertical stems of glyphs + */ + public PDFFontDescriptor(int number, String basefont, int ascent, + int descent, int capHeight, int flags, + PDFRectangle fontBBox, int italicAngle, + int stemV) { + + /* generic creation of PDF object */ + super(number); + + /* set fields using paramaters */ + this.basefont = basefont; + this.ascent = ascent; + this.descent = descent; + this.capHeight = capHeight; + this.flags = flags; + this.fontBBox = fontBBox; + this.italicAngle = italicAngle; + this.stemV = stemV; + } + + /** + * Set the optional metrics. + * @param avgWidth The average width of characters in this font. + * The default value is 0. + * @param maxWidth The maximum width of characters in this font. + * The default value is 0. + * @param missingWidth missing width + * @param leading the desired spacing between lines of text. + * The default value is 0. + * @param stemH The vertical width of the dominant horizontal stems of + * glyphs in the font. The default value is 0. + * @param xHeight The y-coordinate of the top of flat non-ascending + * lowercase letters, measured from the baseline. The default value is 0. + */ + public void setMetrics(int avgWidth, int maxWidth, int missingWidth, + int leading, int stemH, int xHeight) { + this.avgWidth = avgWidth; + this.maxWidth = maxWidth; + this.missingWidth = missingWidth; + this.leading = leading; + this.stemH = stemH; + this.xHeight = xHeight; + } + + /** + * Set the optional font file stream + * + * @param subtype the font type defined in the font stream + * @param fontfile the stream containing an embedded font + */ + public void setFontFile(FontType subtype, PDFStream fontfile) { + this.subtype = subtype; + this.fontfile = fontfile; + } + + // public void setCharSet(){}//for subset fonts + + /** + * Produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(this.number + " " + this.generation + + " obj\n<< /Type /FontDescriptor" + + "\n/FontName /" + this.basefont); + + p.append("\n/FontBBox "); + p.append(fontBBox.toPDFString()); + p.append("\n/Flags "); + p.append(flags); + p.append("\n/CapHeight "); + p.append(capHeight); + p.append("\n/Ascent "); + p.append(ascent); + p.append("\n/Descent "); + p.append(descent); + p.append("\n/ItalicAngle "); + p.append(italicAngle); + p.append("\n/StemV "); + p.append(stemV); + // optional fields + if (stemH != 0) { + p.append("\n/StemH "); + p.append(stemH); + } + if (xHeight != 0) { + p.append("\n/XHeight "); + p.append(xHeight); + } + if (avgWidth != 0) { + p.append("\n/AvgWidth "); + p.append(avgWidth); + } + if (maxWidth != 0) { + p.append("\n/MaxWidth "); + p.append(maxWidth); + } + if (missingWidth != 0) { + p.append("\n/MissingWidth "); + p.append(missingWidth); + } + if (leading != 0) { + p.append("\n/Leading "); + p.append(leading); + } + if (fontfile != null) { + if (subtype == FontType.TYPE1) { + p.append("\n/FontFile "); + } else { + p.append("\n/FontFile2 "); + } + p.append(fontfile.referencePDF()); + } + // charSet for subset fonts // not yet implemented + // CID optional field + fillInPDF(p); + p.append("\n >>\nendobj\n"); + return p.toString().getBytes(); + } + + /** + * Fill in the specifics for the font's descriptor. + *

+ * The given buffer already contains the fields common to all descriptors. + * + * @param begin the buffer to be completed with the specific fields + */ + protected void fillInPDF(StringBuffer begin) { + //nop + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontNonBase14.java b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java new file mode 100644 index 000000000..766e54d45 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java @@ -0,0 +1,140 @@ +/* + * $Id: PDFFontNonBase14.java,v 1.4 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * A common ancestor for Type1, TrueType, MMType1 and Type3 fonts + * (all except base 14 fonts). + */ +public abstract class PDFFontNonBase14 extends PDFFont { + + /** + * first character code in the font + */ + protected int firstChar; + + /** + * last character code in the font + */ + protected int lastChar; + + /** + * widths of characters from firstChar to lastChar + */ + protected PDFArray widths; + + /** + * descriptor of font metrics + */ + protected PDFFontDescriptor descriptor; + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param subtype the font's subtype + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFontNonBase14(int number, String fontname, FontType subtype, + String basefont, + Object encoding) { + + /* generic creation of PDF object */ + super(number, fontname, subtype, basefont, encoding); + + this.descriptor = null; + } + + /** + * Set the width metrics for the font + * + * @param firstChar the first character code in the font + * @param lastChar the last character code in the font + * @param widths an array of size (lastChar - firstChar +1) + */ + public void setWidthMetrics(int firstChar, int lastChar, + PDFArray widths) { + /* set fields using paramaters */ + this.firstChar = firstChar; + this.lastChar = lastChar; + this.widths = widths; + } + + /** + * Set the font descriptor (unused for the Type3 fonts) + * + * @param descriptor the descriptor for other font's metrics + */ + public void setDescriptor(PDFFontDescriptor descriptor) { + this.descriptor = descriptor; + } + + /** + * @see org.apache.fop.pdf.PDFFont#fillInPDF(StringBuffer) + */ + protected void fillInPDF(StringBuffer target) { + target.append("\n/FirstChar "); + target.append(firstChar); + target.append("\n/LastChar "); + target.append(lastChar); + target.append("\n/Widths "); + target.append(this.widths.referencePDF()); + if (descriptor != null) { + target.append("\n/FontDescriptor "); + target.append(this.descriptor.referencePDF()); + } + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontTrueType.java b/src/java/org/apache/fop/pdf/PDFFontTrueType.java new file mode 100644 index 000000000..ca71f8b80 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontTrueType.java @@ -0,0 +1,79 @@ +/* + * $Id: PDFFontTrueType.java,v 1.4 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a TrueType font. + *

+ * In fact everything already done in the superclass. + * Must only define the not default constructor. + */ +public class PDFFontTrueType extends PDFFontNonBase14 { + + /** + * create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFontTrueType(int number, String fontname, + String basefont, + Object encoding) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TRUETYPE, basefont, encoding /* , mapping */); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontType0.java b/src/java/org/apache/fop/pdf/PDFFontType0.java new file mode 100644 index 000000000..7426a5cbf --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontType0.java @@ -0,0 +1,142 @@ +/* + * $Id: PDFFontType0.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a Type0 font. + *

+ * Type0 fonts are specified on page 208 and onwards of the PDF 1.3 spec. + */ +public class PDFFontType0 extends PDFFontNonBase14 { + + /** + * This should be an array of CIDFont but only the first one is used + */ + protected PDFCIDFont descendantFonts; + + /** + * The character map + */ + protected PDFCMap cmap; + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFontType0(int number, String fontname, + String basefont, + Object encoding) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TYPE0, basefont, encoding /* , mapping */); + + /* set fields using paramaters */ + this.descendantFonts = null; + cmap = null; + } + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + * @param descendantFonts the CIDFont upon which this font is based + */ + public PDFFontType0(int number, String fontname, + String basefont, + Object encoding, + PDFCIDFont descendantFonts) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TYPE0, basefont, encoding /* , mapping */); + + /* set fields using paramaters */ + this.descendantFonts = descendantFonts; + } + + /** + * Set the descendant font + * @param descendantFonts the CIDFont upon which this font is based + */ + public void setDescendantFonts(PDFCIDFont descendantFonts) { + this.descendantFonts = descendantFonts; + } + + /** + * Sets the character map + * @param cmap the character map + */ + public void setCMAP(PDFCMap cmap) { + this.cmap = cmap; + } + + /** + * @see org.apache.fop.pdf.PDFFont#fillInPDF(StringBuffer) + */ + protected void fillInPDF(StringBuffer target) { + if (descendantFonts != null) { + target.append("\n/DescendantFonts [ " + + this.descendantFonts.referencePDF() + " ] "); + } + if (cmap != null) { + target.append("\n/ToUnicode " + cmap.referencePDF()); + } + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontType1.java b/src/java/org/apache/fop/pdf/PDFFontType1.java new file mode 100644 index 000000000..51382f07b --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontType1.java @@ -0,0 +1,83 @@ +/* + * $Id: PDFFontType1.java,v 1.4 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a Type1 or MMType1 font (not necessary for the base 14). + *

+ * Type1 fonts are specified on page 201 and onwards of the PDF 1.3 spec. + *
+ * MMType1 fonts are specified on page 205 and onwards of the PDF 1.3 spec. + *

+ * In fact everything already done in the superclass. + * Must only define the not default constructor. + */ +public class PDFFontType1 extends PDFFontNonBase14 { + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFontType1(int number, String fontname, + String basefont, + Object encoding) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TYPE1, basefont, encoding); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFontType3.java b/src/java/org/apache/fop/pdf/PDFFontType3.java new file mode 100644 index 000000000..5c837aded --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFontType3.java @@ -0,0 +1,177 @@ +/* + * $Id: PDFFontType3.java,v 1.4 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.fonts.FontType; + +/** + * Class representing a Type3 font. + *

+ * CAUTION: this is not yet fully implemented!!!!!!! + * the /CharProcs is still missing its toPDF() method. + *

+ * Type3 fonts are specified on page 206 and onwards of the PDF 1.3 spec. + */ +public class PDFFontType3 extends PDFFontNonBase14 { + + /** + * font's required /FontBBox bounding box + */ + protected PDFRectangle fontBBox; + + /** + * font's required /FontMatrix array + */ + protected PDFArray fontMatrix; + + /** + * font's required /CharProcs dictionary + */ + protected PDFCharProcs charProcs; + + /** + * font's optional /Resources object + */ + protected PDFResources resources; + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + */ + public PDFFontType3(int number, String fontname, + String basefont, + Object encoding) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TYPE3, basefont, encoding /* , mapping */); + + this.fontBBox = null; + this.fontMatrix = null; + this.charProcs = null; + } + + /** + * Create the /Font object + * + * @param number the object's number + * @param fontname the internal name for the font + * @param basefont the base font name + * @param encoding the character encoding schema used by the font + * @param fontBBox the font's bounding box + * @param fontMatrix the font's transformation matrix + * @param charProcs the glyphs' definitions + */ + public PDFFontType3(int number, String fontname, + String basefont, + Object encoding, + PDFRectangle fontBBox, PDFArray fontMatrix, + PDFCharProcs charProcs) { + + /* generic creation of PDF object */ + super(number, fontname, FontType.TYPE3, basefont, encoding /* , mapping */); + + this.fontBBox = fontBBox; + this.fontMatrix = fontMatrix; + this.charProcs = charProcs; + } + + /** + * Set the font's bounding box + * + * @param bbox bounding box for the font + */ + public void setFontBBox(PDFRectangle bbox) { + this.fontBBox = bbox; + } + + /** + * Set the font's transformation matrix + * + * @param matrix the transformation matrix for the font + */ + public void setFontMatrix(PDFArray matrix) { + this.fontMatrix = matrix; + } + + /** + * Set the glyphs' definitions. + *

+ * The /CharProcs object needs to be registered in the document's resources. + * + * @param chars the glyphs' dictionary + */ + public void setCharProcs(PDFCharProcs chars) { + this.charProcs = chars; + } + + /** + * @see org.apache.fop.pdf.PDFFont#fillInPDF(StringBuffer) + */ + protected void fillInPDF(StringBuffer target) { + if (fontBBox != null) { + target.append("\n/FontBBox "); + target.append(fontBBox.toPDF()); + } + if (fontMatrix != null) { + target.append("\n/FontMatrix "); + target.append(fontMatrix.toPDF()); + } + if (charProcs != null) { + target.append("\n/CharProcs "); + target.append(charProcs.referencePDF()); + } + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFFormXObject.java b/src/java/org/apache/fop/pdf/PDFFormXObject.java new file mode 100644 index 000000000..8907945f6 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFormXObject.java @@ -0,0 +1,126 @@ +/* + * $Id: PDFFormXObject.java,v 1.3 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.io.IOException; +import java.io.OutputStream; + +/** + * PDF Form XObject + * + * A derivative of the PDFXObject, is a PDF Stream that has not only a + * dictionary but a stream of image data. + */ +public class PDFFormXObject extends PDFXObject { + private PDFStream contents; + private String resRef; + + /** + * create a FormXObject with the given number and name and load the + * image in the object + * + * @param number the pdf object number + * @param xnumber the pdf object X number + * @param cont the pdf stream contents + * @param ref the resource PDF reference + */ + public PDFFormXObject(int number, int xnumber, PDFStream cont, String ref) { + super(number, xnumber, null); + contents = cont; + resRef = ref; + } + + /** + * Output the form stream as PDF. + * This sets up the form XObject dictionary and adds the content + * data stream. + * + * @param stream the output stream to write the data + * @throws IOException if there is an error writing the data + * @return the length of the data written + */ + protected int output(OutputStream stream) throws IOException { + int length = 0; + + String dictEntries = contents.applyFilters(); + + String p = this.number + " " + this.generation + " obj\n"; + p = p + "<>\n"; + + // push the pdf dictionary on the writer + byte[] pdfBytes = p.getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // push all the image data on the writer + // and takes care of length for trailer + length += contents.outputStreamData(stream); + + pdfBytes = ("endobj\n").getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // let it gc + // this object is retained as a reference to inserting + // the same image but the image data is no longer needed + contents = null; + return length; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFFunction.java b/src/java/org/apache/fop/pdf/PDFFunction.java new file mode 100644 index 000000000..38af4ba90 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFFunction.java @@ -0,0 +1,845 @@ +/* + * $Id: PDFFunction.java,v 1.15 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java... +import java.util.List; + +/** + * class representing a PDF Function. + * + * PDF Functions represent parameterized mathematical formulas and + * sampled representations with + * arbitrary resolution. Functions are used in two areas: device-dependent + * rasterization information for halftoning and transfer + * functions, and color specification for smooth shading (a PDF 1.3 feature). + * + * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range. + */ +public class PDFFunction extends PDFObject { + // Guts common to all function types + + /** + * Required: The Type of function (0,2,3,4) default is 0. + */ + protected int functionType = 0; // Default + + /** + * Required: 2 * m Array of Double numbers which are possible inputs to the function + */ + protected List domain = null; + + /** + * Required: 2 * n Array of Double numbers which are possible outputs to the function + */ + protected List range = null; + + /* ********************TYPE 0***************************** */ + // FunctionType 0 specific function guts + + /** + * Required: Array containing the Integer size of the Domain and Range, respectively. + * Note: This is really more like two seperate integers, sizeDomain, and sizeRange, + * but since they're expressed as an array in PDF, my implementation reflects that. + */ + protected List size = null; + + /** + * Required for Type 0: Number of Bits used to represent each sample value. + * Limited to 1,2,4,8,12,16,24, or 32 + */ + protected int bitsPerSample = 1; + + /** + * Optional for Type 0: order of interpolation between samples. + * Limited to linear (1) or cubic (3). Default is 1 + */ + protected int order = 1; + + /** + * Optional for Type 0: A 2 * m array of Doubles which provides a + * linear mapping of input values to the domain. + * + * Required for Type 3: A 2 * k array of Doubles that, taken + * in pairs, map each subset of the domain defined by Domain + * and the Bounds array to the domain of the corresponding function. + * Should be two values per function, usually (0,1), + * as in [0 1 0 1] for 2 functions. + */ + protected List encode = null; + + /** + * Optional for Type 0: A 2 * n array of Doubles which provides + * a linear mapping of sample values to the range. Defaults to Range. + */ + protected List decode = null; + + /** + * Optional For Type 0: A stream of sample values + */ + + /** + * Required For Type 4: Postscript Calculator function + * composed of arithmetic, boolean, and stack operators + boolean constants + */ + protected StringBuffer functionDataStream = null; + + /** + * Required (?) For Type 0: A vector of Strings for the + * various filters to be used to decode the stream. + * These are how the string is compressed. Flate, LZW, etc. + */ + protected List filter = null; + /* *************************TYPE 2************************** */ + + /** + * Required For Type 2: An Array of n Doubles defining + * the function result when x=0. Default is [0]. + */ + protected List cZero = null; + + /** + * Required For Type 2: An Array of n Doubles defining + * the function result when x=1. Default is [1]. + */ + protected List cOne = null; + + /** + * Required for Type 2: The interpolation exponent. + * Each value x will return n results. + * Must be greater than 0. + */ + protected double interpolationExponentN = 1; + + /* *************************TYPE 3************************** */ + + /** + * Required for Type 3: An vector of PDFFunctions which + * form an array of k single input functions making up + * the stitching function. + */ + protected List functions = null; + + /** + * Optional for Type 3: An array of (k-1) Doubles that, + * in combination with Domain, define the intervals to which + * each function from the Functions array apply. Bounds + * elements must be in order of increasing magnitude, + * and each value must be within the value of Domain. + * k is the number of functions. + * If you pass null, it will output (1/k) in an array of k-1 elements. + * This makes each function responsible for an equal amount of the stitching function. + * It makes the gradient even. + */ + protected List bounds = null; + // See encode above, as it's also part of Type 3 Functions. + + /* *************************TYPE 4************************** */ + // See 'data' above. + + /** + * create an complete Function object of Type 0, A Sampled function. + * + * Use null for an optional object parameter if you choose not to use it. + * For optional int parameters, pass the default. + * + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List objects of Double objects. + * This is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theSize A List object of Integer objects. + * This is the number of samples in each input dimension. + * I can't imagine there being more or less than two input dimensions, + * so maybe this should be an array of length 2. + * + * See page 265 of the PDF 1.3 Spec. + * @param theBitsPerSample An int specifying the number of bits + used to represent each sample value. + * Limited to 1,2,4,8,12,16,24 or 32. + * See page 265 of the 1.3 PDF Spec. + * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited + * to 1 (one) or 3, which means linear or cubic-spline interpolation. + * + * This attribute is optional. + * + * See page 265 in the PDF 1.3 spec. + * @param theEncode List objects of Double objects. + * This is the linear mapping of input values intop the domain + * of the function's sample table. Default is hard to represent in + * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. + * This attribute is optional. + * + * See page 265 in the PDF 1.3 spec. + * @param theDecode List objects of Double objects. + * This is a linear mapping of sample values into the range. + * The default is just the range. + * + * This attribute is optional. + * Read about it on page 265 of the PDF 1.3 spec. + * @param theFunctionDataStream The sample values that specify + * the function are provided in a stream. + * + * This is optional, but is almost always used. + * + * Page 265 of the PDF 1.3 spec has more. + * @param theFilter This is a vector of String objects which are the various filters that + * have are to be applied to the stream to make sense of it. Order matters, + * so watch out. + * + * This is not documented in the Function section of the PDF 1.3 spec, + * it was deduced from samples that this is sometimes used, even if we may never + * use it in FOP. It is added for completeness sake. + * @param theNumber The object number of this PDF object. + * @param theFunctionType This is the type of function (0,2,3, or 4). + * It should be 0 as this is the constructor for sampled functions. + */ + public PDFFunction(int theNumber, int theFunctionType, List theDomain, + List theRange, List theSize, int theBitsPerSample, + int theOrder, List theEncode, List theDecode, + StringBuffer theFunctionDataStream, List theFilter) { + super(theNumber); + + this.functionType = 0; // dang well better be 0; + this.size = theSize; + this.bitsPerSample = theBitsPerSample; + this.order = theOrder; // int + this.encode = theEncode; // vector of int + this.decode = theDecode; // vector of int + this.functionDataStream = theFunctionDataStream; + this.filter = theFilter; // vector of Strings + + // the domain and range are actually two dimensional arrays. + // so if there's not an even number of items, bad stuff + // happens. + this.domain = theDomain; + this.range = theRange; + } + + /** + * create an complete Function object of Type 2, an Exponential Interpolation function. + * + * Use null for an optional object parameter if you choose not to use it. + * For optional int parameters, pass the default. + * + * @param theNumber the object's number + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List of Doubles that is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theCZero This is a vector of Double objects which defines the function result + * when x=0. + * + * This attribute is optional. + * It's described on page 268 of the PDF 1.3 spec. + * @param theCOne This is a vector of Double objects which defines the function result + * when x=1. + * + * This attribute is optional. + * It's described on page 268 of the PDF 1.3 spec. + * @param theInterpolationExponentN This is the inerpolation exponent. + * + * This attribute is required. + * PDF Spec page 268 + * @param theFunctionType The type of the function, which should be 2. + */ + public PDFFunction(int theNumber, int theFunctionType, List theDomain, + List theRange, List theCZero, List theCOne, + double theInterpolationExponentN) { + super(theNumber); + + this.functionType = 2; // dang well better be 2; + + this.cZero = theCZero; + this.cOne = theCOne; + this.interpolationExponentN = theInterpolationExponentN; + + + this.domain = theDomain; + this.range = theRange; + + } + + /** + * create an complete Function object of Type 3, a Stitching function. + * + * Use null for an optional object parameter if you choose not to use it. + * For optional int parameters, pass the default. + * + * @param theNumber the object's number + * @param theDomain List objects of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List objects of Double objects. + * This is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theFunctions A List of the PDFFunction objects that the stitching function stitches. + * + * This attributed is required. + * It is described on page 269 of the PDF spec. + * @param theBounds This is a vector of Doubles representing the numbers that, + * in conjunction with Domain define the intervals to which each function from + * the 'functions' object applies. It must be in order of increasing magnitude, + * and each must be within Domain. + * + * It basically sets how much of the gradient each function handles. + * + * This attributed is required. + * It's described on page 269 of the PDF 1.3 spec. + * @param theEncode List objects of Double objects. + * This is the linear mapping of input values intop the domain + * of the function's sample table. Default is hard to represent in + * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. + * This attribute is required. + * + * See page 270 in the PDF 1.3 spec. + * @param theFunctionType This is the function type. It should be 3, + * for a stitching function. + */ + public PDFFunction(int theNumber, int theFunctionType, List theDomain, + List theRange, List theFunctions, + List theBounds, List theEncode) { + super(theNumber); + + this.functionType = 3; // dang well better be 3; + + this.functions = theFunctions; + this.bounds = theBounds; + this.encode = theEncode; + this.domain = theDomain; + this.range = theRange; + + } + + /** + * create an complete Function object of Type 4, a postscript calculator function. + * + * Use null for an optional object parameter if you choose not to use it. + * For optional int parameters, pass the default. + * + * @param theDomain List object of Double objects. + * This is the domain of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theRange List object of Double objects. + * This is the Range of the function. + * See page 264 of the PDF 1.3 Spec. + * @param theFunctionDataStream This is a stream of arithmetic, + * boolean, and stack operators and boolean constants. + * I end up enclosing it in the '{' and '}' braces for you, so don't do it + * yourself. + * + * This attribute is required. + * It's described on page 269 of the PDF 1.3 spec. + * @param theNumber The object number of this PDF object. + * @param theFunctionType The type of function which should be 4, as this is + * a Postscript calculator function + */ + public PDFFunction(int theNumber, int theFunctionType, List theDomain, + List theRange, StringBuffer theFunctionDataStream) { + super(theNumber); + + this.functionType = 4; // dang well better be 4; + this.functionDataStream = theFunctionDataStream; + + this.domain = theDomain; + + this.range = theRange; + + } + + + /** + * represent as PDF. Whatever the FunctionType is, the correct + * representation spits out. The sets of required and optional + * attributes are different for each type, but if a required + * attribute's object was constructed as null, then no error + * is raised. Instead, the malformed PDF that was requested + * by the construction is dutifully output. + * This policy should be reviewed. + * + * @return the PDF string. + */ + public byte[] toPDF() { + int vectorSize = 0; + int numberOfFunctions = 0; + int tempInt = 0; + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + + " obj\n<< \n/FunctionType " + this.functionType + " \n"); + + // FunctionType 0 + if (this.functionType == 0) { + if (this.domain != null) { + // DOMAIN + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + // SIZE + if (this.size != null) { + p.append("/Size [ "); + vectorSize = this.size.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.size.get(tempInt)) + + " "); + } + p.append("] \n"); + } + // ENCODE + if (this.encode != null) { + p.append("/Encode [ "); + vectorSize = this.encode.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt)) + + " "); + } + p.append("] \n"); + } else { + p.append("/Encode [ "); + vectorSize = this.functions.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append("0 1 "); + } + p.append("] \n"); + + } + + // BITSPERSAMPLE + p.append("/BitsPerSample " + this.bitsPerSample); + + // ORDER (optional) + if (this.order == 1 || this.order == 3) { + p.append(" \n/Order " + this.order + " \n"); + } + + // RANGE + if (this.range != null) { + p.append("/Range [ "); + vectorSize = this.range.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) + + " "); + } + + p.append("] \n"); + } + + // DECODE + if (this.decode != null) { + p.append("/Decode [ "); + vectorSize = this.decode.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.decode.get(tempInt)) + + " "); + } + + p.append("] \n"); + } + + // LENGTH + if (this.functionDataStream != null) { + p.append("/Length " + (this.functionDataStream.length() + 1) + + " \n"); + } + + // FILTER? + if (this.filter != null) { // if there's a filter + vectorSize = this.filter.size(); + p.append("/Filter "); + if (vectorSize == 1) { + p.append("/" + ((String)this.filter.get(0)) + + " \n"); + } else { + p.append("[ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append("/" + ((String)this.filter.get(0)) + + " "); + } + p.append("] \n"); + } + } + p.append(">> \n"); + + // stream representing the function + if (this.functionDataStream != null) { + p.append("stream\n" + this.functionDataStream + + "\nendstream\n"); + } + + p.append("endobj\n"); + // end of if FunctionType 0 + + } else if (this.functionType == 2) { + // DOMAIN + if (this.domain != null) { + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + + // RANGE + if (this.range != null) { + p.append("/Range [ "); + vectorSize = this.range.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) + + " "); + } + + p.append("] \n"); + } + + // FunctionType, C0, C1, N are required in PDF + + // C0 + if (this.cZero != null) { + p.append("/C0 [ "); + vectorSize = this.cZero.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.cZero.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + // C1 + if (this.cOne != null) { + p.append("/C1 [ "); + vectorSize = this.cOne.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.cOne.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + // N: The interpolation Exponent + p.append("/N " + + PDFNumber.doubleOut(new Double(this.interpolationExponentN)) + + " \n"); + + p.append(">> \nendobj\n"); + + } else if (this.functionType + == 3) { // fix this up when my eyes uncross + // DOMAIN + if (this.domain != null) { + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + // RANGE + if (this.range != null) { + p.append("/Range [ "); + vectorSize = this.range.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) + + " "); + } + + p.append("] \n"); + } + + // FUNCTIONS + if (this.functions != null) { + p.append("/Functions [ "); + numberOfFunctions = this.functions.size(); + for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) { + p.append(((PDFFunction)this.functions.get(tempInt)).referencePDF() + + " "); + + } + p.append("] \n"); + } + + + // ENCODE + if (this.encode != null) { + p.append("/Encode [ "); + vectorSize = this.encode.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt)) + + " "); + } + + p.append("] \n"); + } else { + p.append("/Encode [ "); + vectorSize = this.functions.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append("0 1 "); + } + p.append("] \n"); + + } + + + // BOUNDS, required, but can be empty + p.append("/Bounds [ "); + if (this.bounds != null) { + + vectorSize = this.bounds.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.bounds.get(tempInt)) + + " "); + } + + } else { + if (this.functions != null) { + // if there are n functions, + // there must be n-1 bounds. + // so let each function handle an equal portion + // of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ] + + String functionsFraction = PDFNumber.doubleOut(new Double(1.0 + / ((double)numberOfFunctions))); + + for (tempInt = 0; tempInt + 1 < numberOfFunctions; + tempInt++) { + + p.append(functionsFraction + " "); + } + functionsFraction = null; // clean reference. + + } + + } + p.append("] \n"); + + + p.append(">> \nendobj\n"); + } else if (this.functionType + == 4) { // fix this up when my eyes uncross + // DOMAIN + if (this.domain != null) { + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + // RANGE + if (this.range != null) { + p.append("/Range [ "); + vectorSize = this.range.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) + + " "); + } + + p.append("] \n"); + } + + // LENGTH + if (this.functionDataStream != null) { + p.append("/Length " + (this.functionDataStream.length() + 1) + + " \n"); + } + + p.append(">> \n"); + + // stream representing the function + if (this.functionDataStream != null) { + p.append("stream\n{ " + this.functionDataStream + + " } \nendstream\n"); + } + + p.append("endobj\n"); + + } + + return (p.toString().getBytes()); + + } + + /** + * Check if this function is equal to another object. + * This is used to find if a particular function already exists + * in a document. + * + * @param obj the obj to compare + * @return true if the functions are equal + */ + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof PDFFunction)) { + return false; + } + PDFFunction func = (PDFFunction)obj; + if (functionType != func.functionType) { + return false; + } + if (bitsPerSample != func.bitsPerSample) { + return false; + } + if (order != func.order) { + return false; + } + if (interpolationExponentN != func.interpolationExponentN) { + return false; + } + if (domain != null) { + if (!domain.equals(func.domain)) { + return false; + } + } else if (func.domain != null) { + return false; + } + if (range != null) { + if (!range.equals(func.range)) { + return false; + } + } else if (func.range != null) { + return false; + } + if (size != null) { + if (!size.equals(func.size)) { + return false; + } + } else if (func.size != null) { + return false; + } + if (encode != null) { + if (!encode.equals(func.encode)) { + return false; + } + } else if (func.encode != null) { + return false; + } + if (decode != null) { + if (!decode.equals(func.decode)) { + return false; + } + } else if (func.decode != null) { + return false; + } + if (functionDataStream != null) { + if (!functionDataStream.equals(func.functionDataStream)) { + return false; + } + } else if (func.functionDataStream != null) { + return false; + } + if (filter != null) { + if (!filter.equals(func.filter)) { + return false; + } + } else if (func.filter != null) { + return false; + } + if (cZero != null) { + if (!cZero.equals(func.cZero)) { + return false; + } + } else if (func.cZero != null) { + return false; + } + if (cOne != null) { + if (!cOne.equals(func.cOne)) { + return false; + } + } else if (func.cOne != null) { + return false; + } + if (functions != null) { + if (!functions.equals(func.functions)) { + return false; + } + } else if (func.functions != null) { + return false; + } + if (bounds != null) { + if (!bounds.equals(func.bounds)) { + return false; + } + } else if (func.bounds != null) { + return false; + } + return true; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFGState.java b/src/java/org/apache/fop/pdf/PDFGState.java new file mode 100644 index 000000000..5b7c20dc1 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFGState.java @@ -0,0 +1,245 @@ +/* + * $Id: PDFGState.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.Map; +import java.util.Iterator; + +/** + * Class representing a /ExtGState object. + */ +public class PDFGState extends PDFObject { + + /** Line width (LW) */ + public static final String GSTATE_LINE_WIDTH = "LW"; + /** Line cap (LC) */ + public static final String GSTATE_LINE_CAP = "LC"; + /** Line join (LJ) */ + public static final String GSTATE_LINE_JOIN = "LJ"; + /** Miter limit (ML) */ + public static final String GSTATE_MITER_LIMIT = "ML"; + /** Dash pattern (D) */ + public static final String GSTATE_DASH_PATTERN = "D"; + /** Rendering intent (RI) */ + public static final String GSTATE_RENDERING_INTENT = "RI"; + /** Overprint for stroke (OP) */ + public static final String GSTATE_OVERPRINT_STROKE = "OP"; + /** Overprint for fill (op) */ + public static final String GSTATE_OVERPRINT_FILL = "op"; + /** Overprint mode (OPM) */ + public static final String GSTATE_OVERPRINT_MODE = "OPM"; + /** Font (Font) */ + public static final String GSTATE_FONT = "Font"; + /** Black generation (BG) */ + public static final String GSTATE_BLACK_GENERATION = "BG"; + /** Black generation with default (BG2) */ + public static final String GSTATE_BLACK_GENERATION2 = "BG2"; + /** Undercolor removal function (UCR) */ + public static final String GSTATE_UNDERCOLOR_REMOVAL = "UCR"; + /** Undercolor removal function with default (UCR2) */ + public static final String GSTATE_UNDERCOLOR_REMOVAL2 = "UCR2"; + /** Transfer function (TR) */ + public static final String GSTATE_TRANSFER_FUNCTION = "TR"; + /** Transfer function with default (TR2) */ + public static final String GSTATE_TRANSFER_FUNCTION2 = "TR2"; + /** Halftone dictionary or stream (HT) */ + public static final String GSTATE_HALFTONE_DICT = "HT"; + /** Halftone phase (HTP, does not show up anymore in PDF 1.4)*/ + public static final String GSTATE_HALFTONE_PHASE = "HTP"; + /** Flatness (FL) */ + public static final String GSTATE_FLATNESS = "FL"; + /** Smoothness (SM) */ + public static final String GSTATE_SMOOTHNESS = "SM"; + /** Strike adjustment (SA) */ + public static final String GSTATE_STRIKE_ADJ = "SA"; + /** Blend mode (BM, PDF 1.4) */ + public static final String GSTATE_BLEND_MODE = "BM"; + /** Soft mask (SMask, PDF 1.4) */ + public static final String GSTATE_SOFT_MASK = "SMask"; + /** Stroking Alpha (CA, PDF 1.4) */ + public static final String GSTATE_ALPHA_STROKE = "CA"; + /** Nonstroking Alpha (ca, PDF 1.4) */ + public static final String GSTATE_ALPHA_NONSTROKE = "ca"; + /** Alpha Source Flag (AIS, PDF 1.4) */ + public static final String GSTATE_ALPHA_SOURCE_FLAG = "AIS"; + /** Text Knockout Flag (TK, PDF 1.4) */ + public static final String GSTATE_TEXT_KNOCKOUT = "TK"; + + + /** Default GState object */ + public static final PDFGState DEFAULT; + + static { + DEFAULT = new PDFGState(0); + Map vals = DEFAULT.values; + /*vals.put(LW, new Float(1.0)); + vals.put(LC, new Integer(0)); + vals.put(LJ, new Integer(0)); + vals.put(ML, new Float(10.0)); + vals.put(D, "0 []"); + vals.put(RI, "RelativeColorimetric"); + vals.put(OP, Boolean.FALSE); + vals.put(op, Boolean.FALSE); + vals.put(OPM, new Integer(1)); + vals.put(Font, "");*/ + + vals.put(GSTATE_ALPHA_STROKE, new Float(1.0)); + vals.put(GSTATE_ALPHA_NONSTROKE, new Float(1.0)); + } + + private Map values = new java.util.HashMap(); + + /** + * Create a /ExtGState object. + * + * @param number the object's number + */ + public PDFGState(int number) { + /* generic creation of object */ + super(number); + } + + /** + * Returns the name of this object + * @return the name + */ + public String getName() { + return "GS" + this.number; + } + + /** + * Sets the alpha value. + * @param val alpha value (0.0 - 1.0) + * @param fill True if alpha should be set for non-stroking operations, + * False if for stroking operations + */ + public void setAlpha(float val, boolean fill) { + if (fill) { + values.put(GSTATE_ALPHA_NONSTROKE, new Float(val)); + } else { + values.put(GSTATE_ALPHA_STROKE, new Float(val)); + } + } + + /** + * Adds all values from another GState object to this one. + * @param state source object to copy from + */ + public void addValues(PDFGState state) { + values.putAll(state.values); + } + + /** + * Adds all values from a Map to this object. + * @param vals source object to copy from + */ + public void addValues(Map vals) { + values.putAll(vals); + } + + /** + * Represent the object in PDF. + * + * @return the PDF string + */ + public byte[] toPDF() { + StringBuffer sb = new StringBuffer(this.number + " " + this.generation + + " obj\n<<\n/Type /ExtGState\n"); + appendVal(sb, GSTATE_ALPHA_NONSTROKE); + appendVal(sb, GSTATE_ALPHA_STROKE); + + sb.append(">>\nendobj\n"); + return sb.toString().getBytes(); + } + + private void appendVal(StringBuffer sb, String name) { + Object val = values.get(name); + if (val != null) { + sb.append("/" + name + " " + val + "\n"); + } + } + + /* + * example + * 29 0 obj + * << + * /Type /ExtGState + * /ca 0.5 + * >> + * endobj + */ + + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof PDFGState)) { + return false; + } + Map vals1 = values; + Map vals2 = ((PDFGState)obj).values; + if (vals1.size() != vals2.size()) { + return false; + } + for (Iterator iter = vals1.keySet().iterator(); iter.hasNext();) { + Object str = iter.next(); + Object obj1 = vals1.get(str); + if (!obj1.equals(vals2.get(str))) { + return false; + } + } + return true; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFGoTo.java b/src/java/org/apache/fop/pdf/PDFGoTo.java new file mode 100644 index 000000000..2011520de --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFGoTo.java @@ -0,0 +1,196 @@ +/* + * $Id: PDFGoTo.java,v 1.10 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a /GoTo object. + * This can either have a Goto to a page reference and location + * or to a specified PDF reference string. + */ +public class PDFGoTo extends PDFAction { + + /** + * the pageReference + */ + private String pageReference; + private String destination = null; + private float xPosition = 0; + private float yPosition = 0; + + /** + * create a /GoTo object. + * + * @param number the object's number + * @param pageReference the pageReference represented by this object + */ + public PDFGoTo(int number, String pageReference) { + /* generic creation of object */ + super(number); + + this.pageReference = pageReference; + } + + /** + * Sets page reference after object has been created + * + * @param pageReference the new page reference to use + */ + public void setPageReference(String pageReference) { + this.pageReference = pageReference; + } + + /** + * Sets the Y position to jump to + * + * @param yPosition y position + */ + public void setYPosition(float yPosition) { + this.yPosition = yPosition; + } + + /** + * Set the destination string for this Goto. + * + * @param dest the PDF destination string + */ + public void setDestination(String dest) { + destination = dest; + } + + /** + * Sets the x Position to jump to + * + * @param xPosition x position + */ + public void setXPosition(int xPosition) { + this.xPosition = (xPosition / 1000f); + } + + /** + * Get the PDF reference for the GoTo action. + * + * @return the PDF reference for the action + */ + public String getAction() { + return referencePDF(); + } + + /** + * represent the object in PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + String dest; + if (destination == null) { + dest = "/D [" + this.pageReference + " /XYZ " + xPosition + + " " + yPosition + " null]\n"; + } else { + dest = "/D [" + this.pageReference + " " + destination + "]\n"; + } + String p = new String(this.number + " " + this.generation + + " obj\n<<\n/S /GoTo\n" + dest + + ">>\nendobj\n"); + return p.getBytes(); + } + + /* + * example + * 29 0 obj + * << + * /S /GoTo + * /D [23 0 R /FitH 600] + * >> + * endobj + */ + + /** + * Check if this equals another object. + * + * @param obj the object to compare + * @return true if this equals other object + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || !(obj instanceof PDFGoTo)) { + return false; + } + + PDFGoTo gt = (PDFGoTo)obj; + + if (gt.pageReference == null) { + if (pageReference != null) { + return false; + } + } else { + if (!gt.pageReference.equals(pageReference)) { + return false; + } + } + + if (destination == null) { + if (!(gt.destination == null && gt.xPosition == xPosition + && gt.yPosition == yPosition)) { + return false; + } + } else { + if (!destination.equals(gt.destination)) { + return false; + } + } + + return true; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFGoToRemote.java b/src/java/org/apache/fop/pdf/PDFGoToRemote.java new file mode 100644 index 000000000..e0019c8c0 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFGoToRemote.java @@ -0,0 +1,184 @@ +/* + * $Id: PDFGoToRemote.java,v 1.7 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a /GoToR object. + */ +public class PDFGoToRemote extends PDFAction { + + /** + * the file specification + */ + private PDFFileSpec pdfFileSpec; + private int pageReference = 0; + private String destination = null; + + /** + * create an GoToR object. + * + * @param number the object's number + * @param pdfFileSpec the fileSpec associated with the action + */ + public PDFGoToRemote(int number, PDFFileSpec pdfFileSpec) { + /* generic creation of object */ + super(number); + + this.pdfFileSpec = pdfFileSpec; + } + + /** + * create an GoToR object. + * + * @param number the object's number + * @param pdfFileSpec the fileSpec associated with the action + * @param page a page reference within the remote document + */ + public PDFGoToRemote(int number, PDFFileSpec pdfFileSpec, int page) { + /* generic creation of object */ + super(number); + + this.pdfFileSpec = pdfFileSpec; + this.pageReference = page; + } + + /** + * create an GoToR object. + * + * @param number the object's number + * @param pdfFileSpec the fileSpec associated with the action + * @param dest a named destination within the remote document + */ + public PDFGoToRemote(int number, PDFFileSpec pdfFileSpec, String dest) { + /* generic creation of object */ + super(number); + + this.pdfFileSpec = pdfFileSpec; + this.destination = dest; + } + + /** + * return the action string which will reference this object + * + * @return the action String + */ + public String getAction() { + return this.referencePDF(); + } + + /** + * represent the object in PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + String p = new String(this.number + " " + this.generation + " obj\n" + + "<<\n/S /GoToR\n" + "/F " + + pdfFileSpec.referencePDF() + "\n"); + + if (destination != null) { + p += "/D (" + this.destination + ")"; + } else { + p += "/D [ " + this.pageReference + " /XYZ null null null ]"; + } + + p += " \n>>\nendobj\n"; + + return p.getBytes(); + } + + + /* + * example + * 28 0 obj + * << + * /S /GoToR + * /F 29 0 R + * /D [ 0 /XYZ -6 797 null ] + * >> + * endobj + */ + + /** + * Check if this equals another object. + * + * @param obj the object to compare + * @return true if this equals other object + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || !(obj instanceof PDFGoToRemote)) { + return false; + } + + PDFGoToRemote remote = (PDFGoToRemote)obj; + + if (!remote.pdfFileSpec.referencePDF().equals(pdfFileSpec.referencePDF())) { + return false; + } + + if (destination != null) { + if (!destination.equals(remote.destination)) { + return false; + } + } else { + if (pageReference != remote.pageReference) { + return false; + } + } + + return true; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFICCStream.java b/src/java/org/apache/fop/pdf/PDFICCStream.java new file mode 100644 index 000000000..039a82fff --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFICCStream.java @@ -0,0 +1,115 @@ +/* + * $Id: PDFICCStream.java,v 1.7 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.awt.color.ICC_Profile; + +/** + * Special PDFStream for ICC profiles (color profiles). + */ +public class PDFICCStream extends PDFStream { + + private int origLength; + private int len1, len3; + + private ICC_Profile cp; + private PDFColorSpace pdfColorSpace; + + /** + * @see org.apache.fop.pdf.PDFObject#PDFObject(int) + */ + public PDFICCStream(int num) { + super(num); + cp = null; + } + + /** + * Sets the color space to encode in PDF. + * @param cp the ICC profile + * @param alt the PDF color space + */ + public void setColorSpace(ICC_Profile cp, PDFColorSpace alt) { + this.cp = cp; + pdfColorSpace = alt; + } + + /** + * overload the base object method so we don't have to copy + * byte arrays around so much + * @see org.apache.fop.pdf.PDFObject#output(OutputStream) + */ + protected int output(java.io.OutputStream stream) + throws java.io.IOException { + + setData(cp.getData()); + + int length = 0; + String filterEntry = applyFilters(); + StringBuffer pb = new StringBuffer(); + pb.append(this.number).append(" ").append(this.generation).append(" obj\n<< "); + pb.append("/N ").append(cp.getNumComponents()).append(" "); + + if (pdfColorSpace != null) { + pb.append("/Alternate /").append(pdfColorSpace.getColorSpacePDFString()).append(" "); + } + + pb.append("/Length ").append((data.getSize() + 1)).append(" ").append(filterEntry); + pb.append(" >>\n"); + byte[] p = pb.toString().getBytes(); + stream.write(p); + length += p.length; + length += outputStreamData(stream); + p = "endobj\n".getBytes(); + stream.write(p); + length += p.length; + return length; + } +} diff --git a/src/java/org/apache/fop/pdf/PDFImage.java b/src/java/org/apache/fop/pdf/PDFImage.java new file mode 100644 index 000000000..b5afc2197 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFImage.java @@ -0,0 +1,159 @@ +/* + * $Id: PDFImage.java,v 1.3 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.IOException; + +/** + * Interface for a PDF image. + * This is used for inserting an image into PDF. + */ +public interface PDFImage { + + /** + * Key to look up XObject. + * This should be a unique key to refer to the image. + * + * @return the key for this image + */ + String getKey(); + + /** + * Setup the PDF image for the current document. + * Some image formats may need to access the document. + * + * @param doc the PDF parent document + */ + void setup(PDFDocument doc); + + /** + * Get the image width in pixels. + * + * @return the image width + */ + int getWidth(); + + /** + * Get the image height in pixels. + * + * @return the image height + */ + int getHeight(); + + /** + * Get the color space for this image. + * Possible results are: DeviceGray, DeviceRGB, or DeviceCMYK + * + * @return the color space + */ + PDFColorSpace getColorSpace(); + + /** + * Get the bits per pixel for this image. + * + * @return the bits per pixel + */ + int getBitsPerPixel(); + + /** + * Check if this image is a PostScript image. + * + * @return true if this is a PostScript image + */ + boolean isPS(); + + /** + * Check if this image has a transparent color transparency. + * + * @return true if it has transparency + */ + boolean isTransparent(); + + /** + * Get the transparent color. + * + * @return the transparent color for this image + */ + PDFColor getTransparentColor(); + + /** + * Get the PDF reference for a bitmap mask. + * + * @return the PDF reference for the mask image + */ + String getMask(); + + /** + * Get the PDF reference for a soft mask. + * + * @return the PDF reference for a soft mask image + */ + String getSoftMask(); + + // get the image bytes, and bytes properties + + /** + * Get the data stream containing the image contents. + * + * @throws IOException if there creating stream + * @return the PDFStream containing the image data + */ + PDFStream getDataStream() throws IOException; + + /** + * Get the ICC stream for this image. + * + * @return the ICC stream for this image if any + */ + PDFICCStream getICCStream(); + +} + diff --git a/src/java/org/apache/fop/pdf/PDFInfo.java b/src/java/org/apache/fop/pdf/PDFInfo.java new file mode 100644 index 000000000..58cafb02d --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFInfo.java @@ -0,0 +1,174 @@ +/* + * $Id: PDFInfo.java,v 1.12 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.Date; +import java.text.SimpleDateFormat; + +/** + * class representing an /Info object + */ +public class PDFInfo extends PDFObject { + + /** + * the application producing the PDF + */ + private String producer; + + private String title = null; + private String author = null; + private String subject = null; + private String keywords = null; + + // the name of the application that created the + // original document before converting to PDF + private String creator; + + /** + * create an Info object + * + * @param number the object's number + */ + public PDFInfo(int number) { + super(number); + } + + /** + * set the producer string + * + * @param producer the producer string + */ + public void setProducer(String producer) { + this.producer = producer; + } + + /** + * set the creator string + * + * @param creator the document creator + */ + public void setCreator(String creator) { + this.creator = creator; + } + + /** + * set the title string + * + * @param t the document title + */ + public void setTitle(String t) { + this.title = t; + } + + /** + * set the author string + * + * @param a the document author + */ + public void setAuthor(String a) { + this.author = a; + } + + /** + * set the subject string + * + * @param s the document subject + */ + public void setSubject(String s) { + this.subject = s; + } + + /** + * set the keywords string + * + * @param k the keywords for this document + */ + public void setKeywords(String k) { + this.keywords = k; + } + + /** + * produce the PDF representation of the object + * + * @return the PDF + */ + public byte[] toPDF() { + String p = this.number + " " + this.generation + + " obj\n<< /Type /Info\n"; + if (title != null) { + p += "/Title (" + this.title + ")\n"; + } + if (author != null) { + p += "/Author (" + this.author + ")\n"; + } + if (subject != null) { + p += "/Subject (" + this.subject + ")\n"; + } + if (keywords != null) { + p += "/Keywords (" + this.keywords + ")\n"; + } + + if (creator != null) { + p += "/Creator (" + this.creator + ")\n"; + } + + p += "/Producer (" + this.producer + ")\n"; + + // creation date in form (D:YYYYMMDDHHmmSSOHH'mm') + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss"); + String str = sdf.format(date) + "+00'00'"; + p += "/CreationDate (D:" + str + ")"; + p += " >>\nendobj\n"; + return p.getBytes(); + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFInternalLink.java b/src/java/org/apache/fop/pdf/PDFInternalLink.java new file mode 100644 index 000000000..812c974cd --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFInternalLink.java @@ -0,0 +1,88 @@ +/* + * $Id: PDFInternalLink.java,v 1.5 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class used to create a PDF internal link + */ +public class PDFInternalLink extends PDFAction { + + private String goToReference; + + /** + * create an internal link instance. + * + * @param goToReference the GoTo Reference to which the link should point + */ + public PDFInternalLink(String goToReference) { + + this.goToReference = goToReference; + } + + /** + * returns the action ncecessary for an internal link + * + * @return the action to place next to /A within a Link + */ + public String getAction() { + return goToReference; + } + + /** + * there is nothing to return for the toPDF method, as it should not be called + * + * @return an empty string + */ + public byte[] toPDF() { + return new byte[0]; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFLink.java b/src/java/org/apache/fop/pdf/PDFLink.java new file mode 100644 index 000000000..23e36e41d --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFLink.java @@ -0,0 +1,163 @@ +/* + * $Id: PDFLink.java,v 1.12 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.awt.geom.Rectangle2D; + +/** + * class representing an /Annot object of /Subtype /Link + */ +public class PDFLink extends PDFObject { + /** + * Used to represent an external link. + */ + public static final int EXTERNAL = 0; + + /** + * Used to represent an internal link. + */ + public static final int INTERNAL = 1; + + private float ulx; + private float uly; + private float brx; + private float bry; + private String color; + private PDFAction action; + + /** + * create objects associated with a link annotation (GoToR) + * + * @param number the object's number + * @param r the rectangle of the link hotspot in absolute coordinates + */ + public PDFLink(int number, Rectangle2D r) { + /* generic creation of PDF object */ + super(number); + + this.ulx = (float)r.getX(); + this.uly = (float)r.getY(); + this.brx = (float)(r.getX() + r.getWidth()); + this.bry = (float)(r.getY() + r.getHeight()); + this.color = "0 0 0"; // just for now + + } + + /** + * Set the pdf action for this link. + * @param action the pdf action that is activated for this link + */ + public void setAction(PDFAction action) { + this.action = action; + } + + /** + * produce the PDF representation of the object + * + * @return the PDF + */ + public byte[] toPDF() { + String p = this.number + " " + this.generation + " obj\n" + + "<< /Type /Annot\n" + "/Subtype /Link\n" + "/Rect [ " + + (ulx) + " " + (uly) + " " + + (brx) + " " + (bry) + " ]\n" + "/C [ " + + this.color + " ]\n" + "/Border [ 0 0 0 ]\n" + "/A " + + this.action.getAction() + "\n" + "/H /I\n>>\nendobj\n"; + return p.getBytes(); + } + + /* + * example + * 19 0 obj + * << + * /Type /Annot + * /Subtype /Link + * /Rect [ 176.032 678.48412 228.73579 692.356 ] + * /C [ 0.86491 0.03421 0.02591 ] + * /Border [ 0 0 1 ] + * /A 28 0 R + * /H /I + * >> + * endobj + */ + + /** + * Check if this equals another object. + * + * @param obj the object to compare + * @return true if this equals other object + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || !(obj instanceof PDFLink)) { + return false; + } + + PDFLink link = (PDFLink)obj; + + if (!((link.ulx == ulx) && (link.uly == uly) + && (link.brx == brx) && (link.bry == bry))) { + return false; + } + + if (!(link.color.equals(color) + && link.action.getAction().equals(action.getAction()))) { + return false; + } + + return true; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFNumber.java b/src/java/org/apache/fop/pdf/PDFNumber.java new file mode 100644 index 000000000..806a2b8d6 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFNumber.java @@ -0,0 +1,147 @@ +/* + * $Id: PDFNumber.java,v 1.9 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * This class contains some utility methods for outputing numbers to PDF. + */ +public class PDFNumber { + + /** prevent instantiation */ + private PDFNumber() { } + + /** + * Output a Double value to a string suitable for PDF. + * + * @param doubleDown the Double value + * @return the value as a string + */ + public static String doubleOut(Double doubleDown) { + return doubleOut(doubleDown.doubleValue()); + } + + /** + * Output a double value to a string suitable for PDF. + * + * @param doubleDown the double value + * @return the value as a string + */ + public static String doubleOut(double doubleDown) { + StringBuffer p = new StringBuffer(); + if (doubleDown < 0) { + doubleDown = -doubleDown; + p.append("-"); + } + double trouble = doubleDown % 1; + + if (trouble > 0.950) { + p.append((int)doubleDown + 1); + } else if (trouble < 0.050) { + p.append((int)doubleDown); + } else { + String doubleString = new String(doubleDown + ""); + int decimal = doubleString.indexOf("."); + if (decimal != -1) { + p.append(doubleString.substring(0, decimal)); + + if ((doubleString.length() - decimal) > 6) { + p.append(doubleString.substring(decimal, decimal + 6)); + } else { + p.append(doubleString.substring(decimal)); + } + } else { + p.append(doubleString); + } + } + return (p.toString()); + } + + /** + * Output a double value to a string suitable for PDF. + * In this method it is possible to set the maximum + * number of decimal places to output. + * + * @param doubleDown the Double value + * @param dec the number of decimal places to output + * @return the value as a string + */ + public static String doubleOut(double doubleDown, int dec) { + StringBuffer p = new StringBuffer(); + if (doubleDown < 0) { + doubleDown = -doubleDown; + p.append("-"); + } + double trouble = doubleDown % 1; + + if (trouble > (1.0 - (5.0 / (Math.pow(10.0, dec))))) { + p.append((int)doubleDown + 1); + } else if (trouble < (5.0 / (Math.pow(10.0, dec)))) { + p.append((int)doubleDown); + } else { + String doubleString = new String(doubleDown + ""); + int decimal = doubleString.indexOf("."); + if (decimal != -1) { + p.append(doubleString.substring(0, decimal)); + + if ((doubleString.length() - decimal) > dec) { + p.append(doubleString.substring(decimal, decimal + dec)); + } else { + p.append(doubleString.substring(decimal)); + } + } else { + p.append(doubleString); + } + } + return (p.toString()); + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java new file mode 100644 index 000000000..2390a57ca --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFObject.java @@ -0,0 +1,128 @@ +/* + * $Id: PDFObject.java,v 1.12 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.io.IOException; +import java.io.OutputStream; + +/** + * generic PDF object. + * + * A PDF Document is essentially a collection of these objects. A PDF + * Object has a number and a generation (although the generation will always + * be 0 in new documents). + */ +public abstract class PDFObject { + + /** + * the object's number + */ + protected int number; + + /** + * the object's generation (0 in new documents) + */ + protected int generation = 0; + + /** + * create an empty object + * + * @param number the object's number + */ + public PDFObject(int number) { + this.number = number; + } + + /** + * Create a PDFObject + */ + public PDFObject() { + // do nothing + } + + /** + * @return the PDF Object number + */ + public int getNumber() { + return this.number; + } + + /** + * write the PDF represention of this object + * + * @param stream the stream to write the PDF to + * @throws IOException if there is an error writing to the stream + * @return the number of bytes written + */ + protected int output(OutputStream stream) throws IOException { + byte[] pdf = this.toPDF(); + stream.write(pdf); + return pdf.length; + } + + /** + * the PDF representation of a reference to this object + * + * @return the reference string + */ + public String referencePDF() { + String p = this.number + " " + this.generation + " R"; + return p; + } + + /** + * represent object as PDF + * + * @return PDF string + */ + abstract byte[] toPDF(); +} diff --git a/src/java/org/apache/fop/pdf/PDFOutline.java b/src/java/org/apache/fop/pdf/PDFOutline.java new file mode 100644 index 000000000..48e54a981 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFOutline.java @@ -0,0 +1,224 @@ +/* + * $Id: PDFOutline.java,v 1.7 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.List; + +/** + * This represents a single Outline object in a PDF, including the root Outlines + * object. Outlines provide the bookmark bar, usually rendered to the right of + * a PDF document in user agents such as Acrobat Reader + * + * @author Kelly A. Campbell + * + */ +public class PDFOutline extends PDFObject { + + /** + * list of sub-entries (outline objects) + */ + private List subentries; + + /** + * parent outline object. Root Outlines parent is null + */ + private PDFOutline parent; + + private PDFOutline prev; + private PDFOutline next; + + private PDFOutline first; + private PDFOutline last; + + private int count; + + /** + * title to display for the bookmark entry + */ + private String title; + + private String actionRef; + + /** + * Create a PDF outline with the title and action. + * + * @param number the object id number + * @param title the title of the outline entry (can only be null for root Outlines obj) + * @param action the action for this outline + */ + public PDFOutline(int number, String title, String action) { + super(number); + subentries = new java.util.ArrayList(); + count = 0; + parent = null; + prev = null; + next = null; + first = null; + last = null; + this.title = title; + actionRef = action; + } + + /** + * Set the title of this Outline object. + * + * @param t the title of the outline + */ + public void setTitle(String t) { + title = t; + } + + /** + * Add a sub element to this outline. + * + * @param outline a sub outline + */ + public void addOutline(PDFOutline outline) { + if (subentries.size() > 0) { + outline.prev = + (PDFOutline)subentries.get(subentries.size() - 1); + outline.prev.next = outline; + } else { + first = outline; + } + + subentries.add(outline); + outline.parent = this; + + // note: count is not just the immediate children + incrementCount(); + + last = outline; + } + + /** + * Increment the number of subentries and descendants. + */ + private void incrementCount() { + // count is a total of our immediate subentries + // and all descendent subentries + count++; + if (parent != null) { + parent.incrementCount(); + } + } + + /** + * represent the object in PDF + * + * @return the PDF for this outline + */ + protected byte[] toPDF() { + StringBuffer result = new StringBuffer(this.number + " " + + this.generation + + " obj\n<<\n"); + if (parent == null) { + // root Outlines object + if (first != null && last != null) { + result.append(" /First " + first.referencePDF() + "\n"); + result.append(" /Last " + last.referencePDF() + "\n"); + // no count... we start with the outline completely closed for now + } + } else { + // subentry Outline object + result.append(" /Title (" + escapeString(title) + ")\n"); + result.append(" /Parent " + parent.referencePDF() + "\n"); + if (first != null && last != null) { + result.append(" /First " + first.referencePDF() + "\n"); + result.append(" /Last " + last.referencePDF() + "\n"); + } + if (prev != null) { + result.append(" /Prev " + prev.referencePDF() + "\n"); + } + if (next != null) { + result.append(" /Next " + next.referencePDF() + "\n"); + } + if (count > 0) { + result.append(" /Count -" + count + "\n"); + } + + if (actionRef != null) { + result.append(" /A " + actionRef + "\n"); + } + + + } + result.append(">> endobj\n"); + return result.toString().getBytes(); + + } + + /** + * escape string (see 3.8.1 in PDF reference 2nd edition) + */ + private String escapeString(String s) { + StringBuffer result = new StringBuffer(); + if (s != null) { + int l = s.length(); + + // byte order marker (0xfeff) + result.append("\\376\\377"); + + for (int i = 0; i < l; i++) { + char ch = s.charAt(i); + int high = (ch & 0xff00) >>> 8; + int low = ch & 0xff; + result.append("\\"); + result.append(Integer.toOctalString(high)); + result.append("\\"); + result.append(Integer.toOctalString(low)); + } + } + + return result.toString(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFPage.java b/src/java/org/apache/fop/pdf/PDFPage.java new file mode 100644 index 000000000..d81e3be52 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFPage.java @@ -0,0 +1,201 @@ +/* + * $Id: PDFPage.java,v 1.21 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a /Page object. + * + * There is one of these for every page in a PDF document. The object + * specifies the dimensions of the page and references a /Resources + * object, a contents stream and the page's parent in the page + * hierarchy. + * + * Modified by Mark Lillywhite, mark-fop@inomial.com. The Parent + * object was being referred to by reference, but all that we + * ever used from the Parent was it's PDF object ID, and according + * to the memory profile this was causing OOM issues. So, we store + * only the object ID of the parent, rather than the parent itself. + */ +public class PDFPage extends PDFResourceContext { + + /** + * the page's parent, a PDF reference object + */ + protected String parent; + + /** + * the contents stream + */ + protected PDFStream contents; + + /** + * the width of the page in points + */ + protected int pagewidth; + + /** + * the height of the page in points + */ + protected int pageheight; + + /** + * Duration to display page + */ + protected int duration = -1; + + /** + * Transition dictionary + */ + protected TransitionDictionary trDictionary = null; + + /** + * create a /Page object + * + * @param doc the PDF document holding this page + * @param number the object's number + * @param resources the /Resources object + * @param contents the content stream + * @param pagewidth the page's width in points + * @param pageheight the page's height in points + */ + public PDFPage(PDFDocument doc, int number, PDFResources resources, PDFStream contents, + int pagewidth, int pageheight) { + + /* generic creation of object */ + super(number, doc, resources); + + /* set fields using parameters */ + this.contents = contents; + this.pagewidth = pagewidth; + this.pageheight = pageheight; + } + + /** + * create a /Page object + * + * @param doc the PDF document holding this page + * @param number the object's number + * @param resources the /Resources object + * @param pagewidth the page's width in points + * @param pageheight the page's height in points + */ + public PDFPage(PDFDocument doc, int number, PDFResources resources, + int pagewidth, int pageheight) { + + /* generic creation of object */ + super(number, doc, resources); + + /* set fields using parameters */ + this.pagewidth = pagewidth; + this.pageheight = pageheight; + } + + /** + * set this page contents + * + * @param contents the contents of the page + */ + public void setContents(PDFStream contents) { + this.contents = contents; + } + + /** + * set this page's parent + * + * @param parent the /Pages object that is this page's parent + */ + public void setParent(PDFPages parent) { + this.parent = parent.referencePDF(); + } + + /** + * Set the transition dictionary and duration. + * This sets the duration of the page and the transition + * dictionary used when going to the next page. + * + * @param dur the duration in seconds + * @param tr the transition dictionary + */ + public void setTransition(int dur, TransitionDictionary tr) { + duration = dur; + trDictionary = tr; + } + + /** + * represent this object as PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + StringBuffer sb = new StringBuffer(); + + sb = sb.append(this.number + " " + this.generation + " obj\n" + + "<< /Type /Page\n" + "/Parent " + + this.parent + "\n" + + "/MediaBox [ 0 0 " + this.pagewidth + " " + + this.pageheight + " ]\n" + "/Resources " + + this.resources.referencePDF() + "\n" + "/Contents " + + this.contents.referencePDF() + "\n"); + if (this.annotList != null) { + sb = sb.append("/Annots " + this.annotList.referencePDF() + "\n"); + } + if (this.duration != -1) { + sb = sb.append("/Dur " + this.duration + "\n"); + } + if (this.trDictionary != null) { + sb = sb.append("/Trans << " + this.trDictionary.getDictionary() + " >>\n"); + } + + sb = sb.append(">>\nendobj\n"); + return sb.toString().getBytes(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFPages.java b/src/java/org/apache/fop/pdf/PDFPages.java new file mode 100644 index 000000000..d5cf9f56c --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFPages.java @@ -0,0 +1,136 @@ +/* + * $Id: PDFPages.java,v 1.16 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.util.List; +import java.util.ArrayList; + +/** + * class representing a /Pages object. + * + * A /Pages object is an ordered collection of pages (/Page objects) + * (Actually, /Pages can contain further /Pages as well but this + * implementation doesn't allow this) + */ +public class PDFPages extends PDFObject { + + /** + * the /Page objects + */ + protected List kids = new ArrayList(); + + /** + * the number of /Page objects + */ + protected int count = 0; + + // private PDFPages parent; + + /** + * create a /Pages object. NOTE: The PDFPages + * object must be created before the PDF document is + * generated, but it is not written to the stream immediately. + * It must aslo be allocated an object ID (so that the kids + * can refer to the parent) so that the XRef table needs to + * be updated before this object is written. + * + * @param number the object's number + */ + public PDFPages(int number) { + super(number); + } + + /** + * add a /Page object. + * + * @param page the PDFPage to add. + */ + public void addPage(PDFPage page) { + this.kids.add(page.referencePDF()); + page.setParent(this); + this.incrementCount(); + } + + /** + * get the count of /Page objects + * + * @return the number of pages + */ + public int getCount() { + return this.count; + } + + /** + * increment the count of /Page objects + */ + public void incrementCount() { + this.count++; + // log.debug("Incrementing count to " + this.getCount()); + } + + /** + * represent the object in PDF + * + * @return the PDF string + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(this.number + " " + this.generation + + " obj\n<< /Type /Pages\n/Count " + + this.getCount() + "\n/Kids ["); + for (int i = 0; i < kids.size(); i++) { + p = p.append(kids.get(i) + " "); + } + p = p.append("] >>\nendobj\n"); + return p.toString().getBytes(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFPathPaint.java b/src/java/org/apache/fop/pdf/PDFPathPaint.java new file mode 100644 index 000000000..dc5170c26 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFPathPaint.java @@ -0,0 +1,109 @@ +/* + * $Id: PDFPathPaint.java,v 1.8 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * Base class for PDF painting operations. + * + */ +public abstract class PDFPathPaint extends PDFObject { + + /** + * The color space for this paint + */ + protected PDFColorSpace colorSpace; + + /** + * Create a path paint with a PDF object number. + * + * @param theNumber the PDF object number + */ + public PDFPathPaint(int theNumber) { + super(theNumber); + } + + /** + * Create an emty path paint. + */ + public PDFPathPaint() { + // do nothing + } + + /** + * Get the PDF string for setting the path paint. + * + * @param fillNotStroke if true fill otherwise stroke + * @return the PDF instruction string + */ + public String getColorSpaceOut(boolean fillNotStroke) { + return (""); + } + + /** + * Set the color space for this paint. + * + * @param theColorSpace the color space value + */ + public void setColorSpace(int theColorSpace) { + this.colorSpace.setColorSpace(theColorSpace); + } + + /** + * Get the current color space value for this paint. + * + * @return the color space value + */ + public int getColorSpace() { + return this.colorSpace.getColorSpace(); + } + +} + diff --git a/src/java/org/apache/fop/pdf/PDFPattern.java b/src/java/org/apache/fop/pdf/PDFPattern.java new file mode 100644 index 000000000..44de1b8d2 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFPattern.java @@ -0,0 +1,453 @@ +/* + * $Id: PDFPattern.java,v 1.18 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java... +import java.util.List; +import java.util.HashMap; +import java.io.OutputStream; +import java.io.IOException; + +/** + * class representing a PDF Function. + * + * PDF Functions represent parameterized mathematical formulas and sampled representations with + * arbitrary resolution. Functions are used in two areas: device-dependent + * rasterization information for halftoning and transfer + * functions, and color specification for smooth shading (a PDF 1.3 feature). + * + * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range. + */ +public class PDFPattern extends PDFPathPaint { + + /** + * The resources associated with this pattern + */ + protected PDFResources resources = null; + + /** + * Either one (1) for tiling, or two (2) for shading. + */ + protected int patternType = 2; // Default + + /** + * The name of the pattern such as "Pa1" or "Pattern1" + */ + protected String patternName = null; + + /** + * 1 for colored pattern, 2 for uncolored + */ + protected int paintType = 2; + + /** + * 1 for constant spacing, 2 for no distortion, and 3 for fast rendering + */ + protected int tilingType = 1; + + /** + * List of Doubles representing the Bounding box rectangle + */ + protected List bBox = null; + + /** + * Horizontal spacing + */ + protected double xStep = -1; + + /** + * Vertical spacing + */ + protected double yStep = -1; + + /** + * The Shading object comprising the Type 2 pattern + */ + protected PDFShading shading = null; + + /** + * List of Integers represetning the Extended unique Identifier + */ + protected List xUID = null; + + /** + * TODO use PDFGState + * String representing the extended Graphics state. + * Probably will never be used like this. + */ + protected StringBuffer extGState = null; + + /** + * List of Doubles representing the Transformation matrix. + */ + protected List matrix = null; + + /** + * The stream of a pattern + */ + protected StringBuffer patternDataStream = null; + + /** + * Create a tiling pattern (type 1). + * + * @param theNumber The object number of this PDF Object + * @param thePatternName The name of the pattern such as "Pa1" or "Pattern1" + * @param theResources the resources associated with this pattern + * @param thePatternType the type of pattern, which is 1 for tiling. + * @param thePaintType 1 or 2, colored or uncolored. + * @param theTilingType 1, 2, or 3, constant spacing, no distortion, or faster tiling + * @param theBBox List of Doubles: The pattern cell bounding box + * @param theXStep horizontal spacing + * @param theYStep vertical spacing + * @param theMatrix Optional List of Doubles transformation matrix + * @param theXUID Optional vector of Integers that uniquely identify the pattern + * @param thePatternDataStream The stream of pattern data to be tiled. + */ + public PDFPattern(int theNumber, String thePatternName, + PDFResources theResources, int thePatternType, // 1 + int thePaintType, int theTilingType, List theBBox, double theXStep, + double theYStep, List theMatrix, List theXUID, + StringBuffer thePatternDataStream) { + super(theNumber); + this.patternName = thePatternName; + + this.resources = theResources; + // This next parameter is implicit to all constructors, and is + // not directly passed. + + this.patternType = 1; // thePatternType; + this.paintType = thePaintType; + this.tilingType = theTilingType; + this.bBox = theBBox; + this.xStep = theXStep; + this.yStep = theYStep; + this.matrix = theMatrix; + this.xUID = theXUID; + this.patternDataStream = thePatternDataStream; + } + + /** + * Create a type 2 pattern (smooth shading) + * + * @param theNumber the object number of this PDF object + * @param thePatternName the name of the pattern + * @param thePatternType the type of the pattern, which is 2, smooth shading + * @param theShading the PDF Shading object that comprises this pattern + * @param theXUID optional:the extended unique Identifier if used. + * @param theExtGState optional: the extended graphics state, if used. + * @param theMatrix Optional:List of Doubles that specify the matrix. + */ + public PDFPattern(int theNumber, String thePatternName, + int thePatternType, PDFShading theShading, + List theXUID, StringBuffer theExtGState, + List theMatrix) { + super(theNumber); + + this.patternName = thePatternName; + + this.patternType = 2; // thePatternType; + this.shading = theShading; + this.xUID = theXUID; + // this isn't really implemented, so it should always be null. + // I just don't want to have to add a new parameter once it is implemented. + this.extGState = theExtGState; // always null + this.matrix = theMatrix; + } + + /** + * Get the name of the pattern + * + * @return String representing the name of the pattern. + */ + public String getName() { + return (this.patternName); + } + + /** + * Get the PDF command for setting to this pattern. + * + * @param fillNotStroke if true fill otherwise stroke + * @return the PDF string for setting the pattern + */ + public String getColorSpaceOut(boolean fillNotStroke) { + if (fillNotStroke) { // fill but no stroke + return ("/Pattern cs /" + this.getName() + " scn \n"); + } else { // stroke (or border) + return ("/Pattern CS /" + this.getName() + " SCN \n"); + } + } + + /** + * represent as PDF. Whatever the FunctionType is, the correct + * representation spits out. The sets of required and optional + * attributes are different for each type, but if a required + * attribute's object was constructed as null, then no error + * is raised. Instead, the malformed PDF that was requested + * by the construction is dutifully output. + * This policy should be reviewed. + * + * @param stream the stream to write to + * @throws IOException if there is an error writing to the stream + * @return the PDF string. + */ + protected int output(OutputStream stream) throws IOException { + + int vectorSize = 0; + int tempInt = 0; + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + + " obj\n<< \n/Type /Pattern \n"); + + if (this.resources != null) { + p.append("/Resources " + this.resources.referencePDF() + " \n"); + } + + p.append("/PatternType " + this.patternType + " \n"); + + PDFStream dataStream = null; + + if (this.patternType == 1) { + p.append("/PaintType " + this.paintType + " \n"); + p.append("/TilingType " + this.tilingType + " \n"); + + if (this.bBox != null) { + vectorSize = this.bBox.size(); + p.append("/BBox [ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.bBox.get(tempInt))); + p.append(" "); + } + p.append("] \n"); + } + p.append("/XStep " + PDFNumber.doubleOut(new Double(this.xStep)) + + " \n"); + p.append("/YStep " + PDFNumber.doubleOut(new Double(this.yStep)) + + " \n"); + + if (this.matrix != null) { + vectorSize = this.matrix.size(); + p.append("/Matrix [ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt))); + p.append(" "); + } + p.append("] \n"); + } + + if (this.xUID != null) { + vectorSize = this.xUID.size(); + p.append("/XUID [ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(((Integer)this.xUID.get(tempInt)) + " "); + } + p.append("] \n"); + } + + // don't forget the length of the stream. + if (this.patternDataStream != null) { + dataStream = new PDFStream(0); + dataStream.add(this.patternDataStream.toString()); + // TODO get the filters from the doc + dataStream.addDefaultFilters(new HashMap(), PDFStream.CONTENT_FILTER); + p.append(dataStream.applyFilters()); + p.append("/Length " + (dataStream.getDataLength() + 1) + + " \n"); + } + + } else { + // if (this.patternType ==2) + // Smooth Shading... + if (this.shading != null) { + p.append("/Shading " + this.shading.referencePDF() + " \n"); + } + + if (this.xUID != null) { + vectorSize = this.xUID.size(); + p.append("/XUID [ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(((Integer)this.xUID.get(tempInt)) + " "); + } + p.append("] \n"); + } + + if (this.extGState != null) { + p.append("/ExtGState " + this.extGState + " \n"); + } + + if (this.matrix != null) { + vectorSize = this.matrix.size(); + p.append("/Matrix [ "); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt))); + p.append(" "); + } + p.append("] \n"); + } + } // end of if patterntype =1...else 2. + + p.append(">> \n"); + + String dict = p.toString(); + int length = dict.length(); + + stream.write(dict.getBytes()); + + // stream representing the function + if (dataStream != null) { + length += dataStream.outputStreamData(stream); + } + + String end = "endobj\n"; + stream.write(end.getBytes()); + length += end.length(); + + return length; + } + + /** + * Output PDF bytes, not used. + * @return returns null + */ + public byte[] toPDF() { return null; } + + /** + * Check if this pattern is equal to another. + * + * @param obj the object to compare against + * @return true if the patterns are equal + */ + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof PDFPattern)) { + return false; + } + PDFPattern patt = (PDFPattern)obj; + if (patternType != patt.patternType) { + return false; + } + if (paintType != patt.paintType) { + return false; + } + if (tilingType != patt.tilingType) { + return false; + } + if (xStep != patt.xStep) { + return false; + } + if (yStep != patt.yStep) { + return false; + } + if (bBox != null) { + if (!bBox.equals(patt.bBox)) { + return false; + } + } else if (patt.bBox != null) { + return false; + } + if (bBox != null) { + if (!bBox.equals(patt.bBox)) { + return false; + } + } else if (patt.bBox != null) { + return false; + } + if (xUID != null) { + if (!xUID.equals(patt.xUID)) { + return false; + } + } else if (patt.xUID != null) { + return false; + } + if (extGState != null) { + if (!extGState.equals(patt.extGState)) { + return false; + } + } else if (patt.extGState != null) { + return false; + } + if (matrix != null) { + if (!matrix.equals(patt.matrix)) { + return false; + } + } else if (patt.matrix != null) { + return false; + } + if (resources != null) { + if (!resources.equals(patt.resources)) { + return false; + } + } else if (patt.resources != null) { + return false; + } + if (shading != null) { + if (!shading.equals(patt.shading)) { + return false; + } + } else if (patt.shading != null) { + return false; + } + if (patternDataStream != null) { + if (!patternDataStream.equals(patt.patternDataStream)) { + return false; + } + } else if (patt.patternDataStream != null) { + return false; + } + + return true; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFRectangle.java b/src/java/org/apache/fop/pdf/PDFRectangle.java new file mode 100644 index 000000000..df4e16dad --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFRectangle.java @@ -0,0 +1,126 @@ +/* + * $Id: PDFRectangle.java,v 1.6 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a rectangle + * + * Rectangles are specified on page 183 of the PDF 1.3 spec. + */ +public class PDFRectangle { + + /** + * lower left x coordinate + */ + protected int llx; + + /** + * lower left y coordinate + */ + protected int lly; + + /** + * upper right x coordinate + */ + protected int urx; + + /** + * upper right y coordinate + */ + protected int ury; + + /** + * create a rectangle giving the four separate values + * + * @param llx lower left x coordinate + * @param lly lower left y coordinate + * @param urx upper right x coordinate + * @param ury upper right y coordinate + */ + public PDFRectangle(int llx, int lly, int urx, int ury) { + this.llx = llx; + this.lly = lly; + this.urx = urx; + this.ury = ury; + } + + /** + * create a rectangle giving an array of four values + * + * @param array values in the order llx, lly, urx, ury + */ + public PDFRectangle(int[] array) { + this.llx = array[0]; + this.lly = array[1]; + this.urx = array[2]; + this.ury = array[3]; + } + + /** + * produce the PDF representation for the object + * + * @return the PDF + */ + public byte[] toPDF() { + return toPDFString().getBytes(); + } + + /** + * Create a PDF string for this rectangle. + * + * @return the pdf string + */ + public String toPDFString() { + return new String(" [" + llx + " " + lly + " " + urx + " " + ury + + "] "); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFResourceContext.java b/src/java/org/apache/fop/pdf/PDFResourceContext.java new file mode 100644 index 000000000..f82ed26a1 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFResourceContext.java @@ -0,0 +1,156 @@ +/* + * $Id: PDFResourceContext.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * The PDF resource context. + * + * There is one of these for every page in a PDF document. The object + * specifies the dimensions of the page and references a /Resources + * object, a contents stream and the page's parent in the page + * hierarchy. + * + * Modified by Mark Lillywhite, mark-fop@inomial.com. The Parent + * object was being referred to by reference, but all that we + * ever used from the Parent was it's PDF object ID, and according + * to the memory profile this was causing OOM issues. So, we store + * only the object ID of the parent, rather than the parent itself. + */ +public class PDFResourceContext extends PDFObject { + + /** + * the page's /Resource object + */ + protected PDFResources resources; + + /** + * the list of annotation objects for this page + */ + protected PDFAnnotList annotList; + + /** + * Reference to document used when creating annotation list + */ + protected PDFDocument document; + + /** + * + * @param number the object's number + * @param doc the PDF document this belongs to + * @param resources the /Resources object + */ + public PDFResourceContext(int number, PDFDocument doc, PDFResources resources) { + /* generic creation of object */ + super(number); + + /* set fields using parameters */ + this.document = doc; + this.resources = resources; + this.annotList = null; + } + + /** + * Get the resources for this resource context. + * + * @return the resources in this resource context + */ + public PDFResources getPDFResources() { + return this.resources; + } + + /** + * set this page's annotation list + * + * @param annot a PDFAnnotList list of annotations + */ + public void addAnnotation(PDFObject annot) { + if (this.annotList == null) { + this.annotList = document.makeAnnotList(); + } + this.annotList.addAnnot(annot); + } + + /** + * Get the current annotations. + * + * @return the current annotation list + */ + public PDFAnnotList getAnnotations() { + return this.annotList; + } + + /** + * A a GState to this resource context. + * + * @param gstate the GState to add + */ + public void addGState(PDFGState gstate) { + this.resources.addGState(gstate); + } + + /** + * Add the shading tot he current resource context. + * + * @param shading the shading to add + */ + public void addShading(PDFShading shading) { + this.resources.addShading(shading); + } + + /** + * Get the PDF, unused. + * + * @return null value + */ + public byte[] toPDF() { + return null; + } +} diff --git a/src/java/org/apache/fop/pdf/PDFResources.java b/src/java/org/apache/fop/pdf/PDFResources.java new file mode 100644 index 000000000..ffc7c5b0a --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFResources.java @@ -0,0 +1,232 @@ +/* + * $Id: PDFResources.java,v 1.17 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.HashSet; + +/** + * class representing a /Resources object. + * + * /Resources object contain a list of references to the fonts for the + * document + */ +public class PDFResources extends PDFObject { + + /** + * /Font objects keyed by their internal name + */ + protected Map fonts = new HashMap(); + + /** + * Set of XObjects + */ + protected Set xObjects = new HashSet(); + + /** + * Set of patterns + */ + protected Set patterns = new HashSet(); + + /** + * Set of shadings + */ + protected Set shadings = new HashSet(); + + /** + * Set of ExtGStates + */ + protected Set gstates = new HashSet(); + + /** + * create a /Resources object. + * + * @param number the object's number + */ + public PDFResources(int number) { + /* generic creation of object */ + super(number); + } + + /** + * add font object to resources list. + * + * @param font the PDFFont to add + */ + public void addFont(PDFFont font) { + this.fonts.put(font.getName(), font); + } + + /** + * Add a PDFGState to the resources. + * + * @param gs the PDFGState to add + */ + public void addGState(PDFGState gs) { + this.gstates.add(gs); + } + + /** + * Add a Shading to the resources. + * + * @param theShading the shading to add + */ + public void addShading(PDFShading theShading) { + this.shadings.add(theShading); + } + + /** + * Add the pattern to the resources. + * + * @param thePattern the pattern to add + */ + public void addPattern(PDFPattern thePattern) { + this.patterns.add(thePattern); + } + + /** + * Add an XObject to the resources. + * + * @param xObject the XObject to add + */ + public void addXObject(PDFXObject xObject) { + this.xObjects.add(xObject); + } + + /** + * represent the object in PDF + * This adds the references to all the objects in the current + * resource context. + * + * @return the PDF + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(this.number + " " + this.generation + + " obj\n<< \n"); + if (!this.fonts.isEmpty()) { + p.append("/Font << "); + + /* construct PDF dictionary of font object references */ + Iterator fontIterator = this.fonts.keySet().iterator(); + while (fontIterator.hasNext()) { + String fontName = (String)fontIterator.next(); + p.append("/" + fontName + " " + + ((PDFFont)this.fonts.get(fontName)).referencePDF() + + " "); + } + + p.append(">> \n"); + } + + PDFShading currentShading = null; + if (!this.shadings.isEmpty()) { + p.append("/Shading << "); + + for (Iterator iter = shadings.iterator(); iter.hasNext();) { + currentShading = (PDFShading)iter.next(); + p.append("/" + currentShading.getName() + " " + + currentShading.referencePDF() + " "); // \n ?????? + } + + p.append(">>\n"); + } + // "free" the memory. Sorta. + currentShading = null; + + PDFPattern currentPattern = null; + if (!this.patterns.isEmpty()) { + p.append("/Pattern << "); + + for (Iterator iter = patterns.iterator(); iter.hasNext();) { + currentPattern = (PDFPattern)iter.next(); + p.append("/" + currentPattern.getName() + " " + + currentPattern.referencePDF() + " "); + } + + p.append(">> \n"); + } + // "free" the memory. Sorta. + currentPattern = null; + + p.append("/ProcSet [ /PDF /ImageC /Text ]\n"); + + if (this.xObjects != null && !this.xObjects.isEmpty()) { + p = p.append("/XObject <<"); + for (Iterator iter = xObjects.iterator(); iter.hasNext();) { + PDFXObject xobj = (PDFXObject)iter.next(); + p = p.append("/Im" + xobj.getXNumber() + " " + + xobj.referencePDF() + + "\n"); + } + p = p.append(" >>\n"); + } + + if (!this.gstates.isEmpty()) { + p = p.append("/ExtGState <<"); + for (Iterator iter = gstates.iterator(); iter.hasNext();) { + PDFGState gs = (PDFGState)iter.next(); + p = p.append("/" + gs.getName() + " " + + gs.referencePDF() + + " "); + } + p = p.append(">>\n"); + } + + p = p.append(">>\nendobj\n"); + + return p.toString().getBytes(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java new file mode 100644 index 000000000..a803ea0b7 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFRoot.java @@ -0,0 +1,183 @@ +/* + * $Id: PDFRoot.java,v 1.14 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class representing a Root (/Catalog) object + */ +public class PDFRoot extends PDFObject { + + /** + * Use no page mode setting, default + */ + public static final int PAGEMODE_USENONE = 0; + + /** + * Use outlines page mode to show bookmarks + */ + public static final int PAGEMODE_USEOUTLINES = 1; + + /** + * Use thumbs page mode to show thumbnail images + */ + public static final int PAGEMODE_USETHUMBS = 2; + + /** + * Full screen page mode + */ + public static final int PAGEMODE_FULLSCREEN = 3; + + /** + * the /Pages object that is root of the Pages hierarchy + */ + protected PDFPages rootPages; + + /** + * Root outline object + */ + private PDFOutline outline; + + private int pageMode = PAGEMODE_USENONE; + + /** + * create a Root (/Catalog) object. NOTE: The PDFRoot + * object must be created before the PDF document is + * generated, but it is not assigned an object ID until + * it is about to be written (immediately before the xref + * table as part of the trsailer). (mark-fop@inomial.com) + * + * @param number the object's number + * @param pages the PDFPages object + */ + public PDFRoot(int number, PDFPages pages) { + super(number); + setRootPages(pages); + } + + /** + * Set the page mode for the PDF document. + * + * @param mode the page mode + */ + public void setPageMode(int mode) { + pageMode = mode; + } + + /** + * add a /Page object to the root /Pages object + * + * @param page the /Page object to add + */ + public void addPage(PDFPage page) { + this.rootPages.addPage(page); + } + + /** + * set the root /Pages object + * + * @param pages the /Pages object to set as root + */ + public void setRootPages(PDFPages pages) { + this.rootPages = pages; + } + + /** + * Set the root outline for the PDF document. + * + * @param out the root PDF Outline + */ + public void setRootOutline(PDFOutline out) { + outline = out; + } + + /** + * Get the root PDF outline for the document. + * + * @return the root PDF Outline + */ + public PDFOutline getRootOutline() { + return outline; + } + + /** + * represent the object as PDF. + * + * @return the PDF string + */ + public byte[] toPDF() { + StringBuffer p = new StringBuffer(this.number + " " + this.generation + + " obj\n<< /Type /Catalog\n/Pages " + + this.rootPages.referencePDF() + + "\n"); + if (outline != null) { + p.append(" /Outlines " + outline.referencePDF() + "\n"); + p.append(" /PageMode /UseOutlines\n"); + } else { + switch (pageMode) { + case PAGEMODE_USEOUTLINES: + p.append(" /PageMode /UseOutlines\n"); + break; + case PAGEMODE_USETHUMBS: + p.append(" /PageMode /UseThumbs\n"); + break; + case PAGEMODE_FULLSCREEN: + p.append(" /PageMode /FullScreen\n"); + break; + case PAGEMODE_USENONE: + default: + break; + } + } + p.append(" >>\nendobj\n"); + return p.toString().getBytes(); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFShading.java b/src/java/org/apache/fop/pdf/PDFShading.java new file mode 100644 index 000000000..13220f22c --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFShading.java @@ -0,0 +1,670 @@ +/* + * $Id: PDFShading.java,v 1.14 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java... +import java.util.List; + +/** + * class representing a PDF Smooth Shading object. + * + * PDF Functions represent parameterized mathematical formulas and sampled representations with + * arbitrary resolution. Functions are used in two areas: device-dependent + * rasterization information for halftoning and transfer + * functions, and color specification for smooth shading (a PDF 1.3 feature). + * + * All PDF Functions have a shadingType (0,2,3, or 4), a Domain, and a Range. + */ +public class PDFShading extends PDFObject { + // Guts common to all function types + + /** + * The name of the Shading e.g. "Shading1" + */ + protected String shadingName = null; + + /** + * Required: The Type of shading (1,2,3,4,5,6,7) + */ + protected int shadingType = 3; // Default + + /** + * A ColorSpace representing the colorspace. "DeviceRGB" is an example. + */ + protected PDFColorSpace colorSpace = null; + + /** + * The background color. Since shading is opaque, + * this is very rarely used. + */ + protected List background = null; + + /** + * Optional: A List specifying the clipping rectangle + */ + protected List bBox = null; + + /** + * Optional: A flag whether or not to filter the shading function + * to prevent aliasing artifacts. Default is false. + */ + protected boolean antiAlias = false; + + /** + * Optional for Type 1: Array of four numbers, xmin, xmax, ymin, ymax. + * Default is [0 1 0 1] + * Optional for Type 2: An array of two numbers between which the blend + * varies between start and end points. Default is 0, 1. + * Optional for Type 3: An array of two numbers between which the blend + * varies between start and end points. Default is 0, 1. + */ + protected List domain = null; + + /** + * Optional for Type 1: A transformation matrix + */ + protected List matrix = null; + + /** + * Required for Type 1, 2, and 3: + * The object of the color mapping function (usually type 2 or 3). + * Optional for Type 4,5,6, and 7: When it's nearly the same thing. + */ + protected PDFFunction function = null; + + /** + * Required for Type 2: An Array of four numbers specifying + * the starting and ending coordinate pairs + * Required for Type 3: An Array of six numbers [x0,y0,r0,x1,y1,r1] + * specifying the centers and radii of + * the starting and ending circles. + */ + protected List coords = null; + + /** + * Required for Type 2+3: An Array of two boolean values specifying + * whether to extend the start and end colors past the start + * and end points, respectively. + * Default is false, false. + */ + protected List extend = null; + + /** + * Required for Type 4,5,6, and 7: Specifies the number of bits used + * to represent each vertex coordinate. + * Allowed to be 1,2,4,8,12,16,24, or 32. + */ + protected int bitsPerCoordinate = 0; + + /** + * Required for Type 4,5,6, and 7: Specifies the number of bits used + * to represent the edge flag for each vertex. + * Allowed to be 2,4,or 8, while the Edge flag itself is allowed to + * be 0,1 or 2. + */ + protected int bitsPerFlag = 0; + + /** + * Required for Type 4,5,6, and 7: Array of Doubles which specifies + * how to decode coordinate and color component values. + * Each type has a differing number of decode array members, so check + * the spec. + * Page 303 in PDF Spec 1.3 + */ + protected List decode = null; + + /** + * Required for Type 4,5,6, and 7: Specifies the number of bits used + * to represent each color coordinate. + * Allowed to be 1,2,4,8,12, or 16 + */ + protected int bitsPerComponent = 0; + + /** + * Required for Type 5:The number of vertices in each "row" of + * the lattice; it must be greater than or equal to 2. + */ + protected int verticesPerRow = 0; + + /** + * Constructor for type function based shading + * + * @param theNumber The object number of this PDF object + * @param theShadingName The name of the shading pattern. Can be anything + * without spaces. "Shading1" or "Sh1" are good examples. + * @param theShadingType The type of shading object, which should be 1 for function + * based shading. + * @param theColorSpace The colorspace is 'DeviceRGB' or something similar. + * @param theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Whether or not to anti-alias. + * @param theDomain Optional vector of Doubles specifying the domain. + * @param theMatrix List of Doubles specifying the matrix. + * If it's a pattern, then the matrix maps it to pattern space. + * If it's a shading, then it maps it to current user space. + * It's optional, the default is the identity matrix + * @param theFunction The PDF Function that maps an (x,y) location to a color + */ + public PDFShading(int theNumber, String theShadingName, + int theShadingType, PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, List theDomain, + List theMatrix, PDFFunction theFunction) { + super(theNumber); + this.shadingName = theShadingName; + this.shadingType = theShadingType; // 1 + this.colorSpace = theColorSpace; + this.background = theBackground; + this.bBox = theBBox; + this.antiAlias = theAntiAlias; + + this.domain = theDomain; + this.matrix = theMatrix; + this.function = theFunction; + + } + + /** + * Constructor for Type 2 and 3 + * + * @param theNumber The object number of this PDF object. + * @param theShadingName The name of the shading pattern. Can be anything + * without spaces. "Shading1" or "Sh1" are good examples. + * @param theShadingType 2 or 3 for axial or radial shading + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theCoords List of four (type 2) or 6 (type 3) Double + * @param theDomain List of Doubles specifying the domain + * @param theFunction the Stitching (PDFfunction type 3) function, + * even if it's stitching a single function + * @param theExtend List of Booleans of whether to extend the start + * and end colors past the start and end points + * The default is [false, false] + */ + public PDFShading(int theNumber, String theShadingName, + int theShadingType, PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, List theCoords, + List theDomain, PDFFunction theFunction, + List theExtend) { + super(theNumber); + this.shadingName = theShadingName; + this.shadingType = theShadingType; // 2 or 3 + this.colorSpace = theColorSpace; + this.background = theBackground; + this.bBox = theBBox; + this.antiAlias = theAntiAlias; + + this.coords = theCoords; + this.domain = theDomain; + this.function = theFunction; + this.extend = theExtend; + + } + + /** + * Constructor for Type 4,6, or 7 + * + * @param theNumber The object number of this PDF object. + * @param theShadingType 4, 6, or 7 depending on whether it's + * Free-form gouraud-shaded triangle meshes, coons patch meshes, + * or tensor product patch meshes, respectively. + * @param theShadingName The name of the shading pattern. Can be anything + * without spaces. "Shading1" or "Sh1" are good examples. + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theBitsPerCoordinate 1,2,4,8,12,16,24 or 32. + * @param theBitsPerComponent 1,2,4,8,12, and 16 + * @param theBitsPerFlag 2,4,8. + * @param theDecode List of Doubles see PDF 1.3 spec pages 303 to 312. + * @param theFunction the PDFFunction + */ + public PDFShading(int theNumber, String theShadingName, + int theShadingType, PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, int theBitsPerCoordinate, + int theBitsPerComponent, int theBitsPerFlag, + List theDecode, PDFFunction theFunction) { + super(theNumber); + + this.shadingType = theShadingType; // 4,6 or 7 + this.colorSpace = theColorSpace; + this.background = theBackground; + this.bBox = theBBox; + this.antiAlias = theAntiAlias; + + this.bitsPerCoordinate = theBitsPerCoordinate; + this.bitsPerComponent = theBitsPerComponent; + this.bitsPerFlag = theBitsPerFlag; + this.decode = theDecode; + this.function = theFunction; + } + + /** + * Constructor for type 5 + * + * @param theShadingType 5 for lattice-Form Gouraud shaded-triangle mesh + * @param theShadingName The name of the shading pattern. Can be anything + * without spaces. "Shading1" or "Sh1" are good examples. + * @param theColorSpace "DeviceRGB" or similar. + * @param theBackground theBackground An array of color components appropriate to the + * colorspace key specifying a single color value. + * This key is used by the f operator buy ignored by the sh operator. + * @param theBBox List of double's representing a rectangle + * in the coordinate space that is current at the + * time of shading is imaged. Temporary clipping + * boundary. + * @param theAntiAlias Default is false + * @param theBitsPerCoordinate 1,2,4,8,12,16, 24, or 32 + * @param theBitsPerComponent 1,2,4,8,12,24,32 + * @param theDecode List of Doubles. See page 305 in PDF 1.3 spec. + * @param theVerticesPerRow number of vertices in each "row" of the lattice. + * @param theFunction The PDFFunction that's mapped on to this shape + * @param theNumber the object number of this PDF object. + */ + public PDFShading(int theNumber, String theShadingName, + int theShadingType, PDFColorSpace theColorSpace, + List theBackground, List theBBox, + boolean theAntiAlias, int theBitsPerCoordinate, + int theBitsPerComponent, List theDecode, + int theVerticesPerRow, PDFFunction theFunction) { + super(theNumber); + this.shadingName = theShadingName; + this.shadingType = theShadingType; // 5 + this.colorSpace = theColorSpace; + this.background = theBackground; + this.bBox = theBBox; + this.antiAlias = theAntiAlias; + + this.bitsPerCoordinate = theBitsPerCoordinate; + this.bitsPerComponent = theBitsPerComponent; + this.decode = theDecode; + this.verticesPerRow = theVerticesPerRow; + this.function = theFunction; + + } + + /** + * Get the name of this shading. + * + * @return the name of the shading + */ + public String getName() { + return (this.shadingName); + } + + /** + * represent as PDF. Whatever the shadingType is, the correct + * representation spits out. The sets of required and optional + * attributes are different for each type, but if a required + * attribute's object was constructed as null, then no error + * is raised. Instead, the malformed PDF that was requested + * by the construction is dutifully output. + * This policy should be reviewed. + * + * @return the PDF string. + */ + public byte[] toPDF() { + int vectorSize; + int tempInt; + StringBuffer p = new StringBuffer(); + p.append(this.number + " " + this.generation + + " obj\n<< \n/ShadingType " + this.shadingType + " \n"); + if (this.colorSpace != null) { + p.append("/ColorSpace /" + + this.colorSpace.getColorSpacePDFString() + " \n"); + } + + if (this.background != null) { + p.append("/Background [ "); + vectorSize = this.background.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.background.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + if (this.bBox + != null) { // I've never seen an example, so I guess this is right. + p.append("/BBox [ "); + vectorSize = this.bBox.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.bBox.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + if (this.antiAlias) { + p.append("/AntiAlias " + this.antiAlias + " \n"); + } + + // Here's where we differentiate based on what type it is. + if (this.shadingType == 1) { // function based shading + if (this.domain != null) { + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + if (this.matrix != null) { + p.append("/Matrix [ "); + vectorSize = this.matrix.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + if (this.function != null) { + p.append("/Function "); + p.append(this.function.referencePDF() + " \n"); + } + } else if ((this.shadingType == 2) + || (this.shadingType + == 3)) { // 2 is axial shading (linear gradient) + // 3 is radial shading (circular gradient) + if (this.coords != null) { + p.append("/Coords [ "); + vectorSize = this.coords.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.coords.get(tempInt)) + + " "); + } + p.append("] \n"); + } + + // DOMAIN + if (this.domain != null) { + p.append("/Domain [ "); + vectorSize = this.domain.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) + + " "); + } + p.append("] \n"); + } else { + p.append("/Domain [ 0 1 ] \n"); + } + + if (this.extend != null) { + p.append("/Extend [ "); + vectorSize = this.extend.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(((Boolean)this.extend.get(tempInt)) + " "); + } + + p.append("] \n"); + } else { + p.append("/Extend [ true true ] \n"); + } + + + if (this.function != null) { + p.append("/Function "); + p.append(this.function.referencePDF() + " \n"); + } + + + } else if ((this.shadingType == 4) || (this.shadingType == 6) + || (this.shadingType + == 7)) { // 4:Free-form Gouraud-shaded triangle meshes + // 6:coons patch meshes + // 7://tensor product patch meshes (which no one ever uses) + if (this.bitsPerCoordinate > 0) { + p.append("/BitsPerCoordinate " + this.bitsPerCoordinate + + " \n"); + } else { + p.append("/BitsPerCoordinate 1 \n"); + } + + if (this.bitsPerComponent > 0) { + p.append("/BitsPerComponent " + this.bitsPerComponent + + " \n"); + } else { + p.append("/BitsPerComponent 1 \n"); + } + + if (this.bitsPerFlag > 0) { + p.append("/BitsPerFlag " + this.bitsPerFlag + " \n"); + } else { + p.append("/BitsPerFlag 2 \n"); + } + + if (this.decode != null) { + p.append("/Decode [ "); + vectorSize = this.decode.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(((Boolean)this.decode.get(tempInt)) + " "); + } + + p.append("] \n"); + } + + if (this.function != null) { + p.append("/Function "); + p.append(this.function.referencePDF() + " \n"); + } + + } else if (this.shadingType + == 5) { // Lattice Free form gouraud-shaded triangle mesh + + if (this.bitsPerCoordinate > 0) { + p.append("/BitsPerCoordinate " + this.bitsPerCoordinate + + " \n"); + } else { + p.append("/BitsPerCoordinate 1 \n"); + } + + if (this.bitsPerComponent > 0) { + p.append("/BitsPerComponent " + this.bitsPerComponent + + " \n"); + } else { + p.append("/BitsPerComponent 1 \n"); + } + + if (this.decode != null) { + p.append("/Decode [ "); + vectorSize = this.decode.size(); + for (tempInt = 0; tempInt < vectorSize; tempInt++) { + p.append(((Boolean)this.decode.get(tempInt)) + " "); + } + + p.append("] \n"); + } + + if (this.function != null) { + p.append("/Function "); + p.append(this.function.referencePDF() + " \n"); + } + + if (this.verticesPerRow > 0) { + p.append("/VerticesPerRow " + this.verticesPerRow + " \n"); + } else { + p.append("/VerticesPerRow 2 \n"); + } + + } + + p.append(">> \nendobj\n"); + + return (p.toString().getBytes()); + } + + /** + * Check if this shading is equal to another shading. + * This is used to check if a shading already exists. + * + * @param obj the object to compare against + * @return true if the shadings are equal + */ + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof PDFShading)) { + return false; + } + PDFShading shad = (PDFShading)obj; + if (shadingType != shad.shadingType) { + return false; + } + if (antiAlias != shad.antiAlias) { + return false; + } + if (bitsPerCoordinate != shad.bitsPerCoordinate) { + return false; + } + if (bitsPerFlag != shad.bitsPerFlag) { + return false; + } + if (bitsPerComponent != shad.bitsPerComponent) { + return false; + } + if (verticesPerRow != shad.verticesPerRow) { + return false; + } + if (colorSpace != null) { + if (!colorSpace.equals(shad.colorSpace)) { + return false; + } + } else if (shad.colorSpace != null) { + return false; + } + if (background != null) { + if (!background.equals(shad.background)) { + return false; + } + } else if (shad.background != null) { + return false; + } + if (bBox != null) { + if (!bBox.equals(shad.bBox)) { + return false; + } + } else if (shad.bBox != null) { + return false; + } + if (domain != null) { + if (!domain.equals(shad.domain)) { + return false; + } + } else if (shad.domain != null) { + return false; + } + if (matrix != null) { + if (!matrix.equals(shad.matrix)) { + return false; + } + } else if (shad.matrix != null) { + return false; + } + if (coords != null) { + if (!coords.equals(shad.coords)) { + return false; + } + } else if (shad.coords != null) { + return false; + } + if (extend != null) { + if (!extend.equals(shad.extend)) { + return false; + } + } else if (shad.extend != null) { + return false; + } + if (decode != null) { + if (!decode.equals(shad.decode)) { + return false; + } + } else if (shad.decode != null) { + return false; + } + if (function != null) { + if (!function.equals(shad.function)) { + return false; + } + } else if (shad.function != null) { + return false; + } + return true; + } +} diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFState.java new file mode 100644 index 000000000..289d20292 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFState.java @@ -0,0 +1,385 @@ +/* + * $Id: PDFState.java,v 1.9 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.awt.Shape; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.awt.geom.GeneralPath; +import java.awt.geom.Area; + +import java.awt.Color; +import java.awt.Paint; +import java.awt.geom.AffineTransform; + +/** + * This keeps information about the current state when writing to pdf. + * It allows for creating new graphics states with the q operator. + * This class is only used to store the information about the state + * the caller needs to handle the actual pdf operators. + * + * When setting the state for pdf there are three possible ways of + * handling the situation. + * The values can be set to override previous or default values. + * A new state can be added and then the values set. + * The current state can be popped and values will return to a + * previous state then the necessary values can be overridden. + * The current transform behaves differently to other values as the + * matrix is combined with the current resolved value. + * It is impossible to optimise the result without analysing the all + * the possible combinations after completing. + */ +public class PDFState { + private static final String COLOR = "color"; + private static final String BACKCOLOR = "backcolor"; + private static final String PAINT = "paint"; + private static final String BACKPAINT = "backpaint"; + private static final String LINECAP = "lineCap"; + private static final String LINEJOIN = "lineJoin"; + private static final String LINEWIDTH = "lineWidth"; + private static final String MITERLIMIT = "miterLimit"; + private static final String TEXT = "text"; + private static final String DASHOFFSET = "dashOffset"; + private static final String DASHARRAY = "dashArray"; + private static final String TRANSFORM = "transform"; + private static final String FONTSIZE = "fontSize"; + private static final String FONTNAME = "fontName"; + private static final String CLIP = "clip"; + private static final String GSTATE = "gstate"; + + private Color color = Color.black; + private Color backcolor = Color.white; + private Paint paint = null; + private Paint backPaint = null; + private int lineCap = 0; + private int lineJoin = 0; + private float lineWidth = 1; + private float miterLimit = 0; + private boolean text = false; + private int dashOffset = 0; + private int[] dashArray = new int[0]; + private AffineTransform transform = new AffineTransform(); + private float fontSize = 0; + private String fontName = ""; + private Shape clip = null; + private PDFGState gstate = null; + + private ArrayList stateStack = new ArrayList(); + + /** + * PDF State for storing graphics state. + */ + public PDFState() { + + } + + /** + * Push the current state onto the stack. + * This call should be used when the q operator is used + * so that the state is known when popped. + */ + public void push() { + HashMap saveMap = new HashMap(); + saveMap.put(COLOR, color); + saveMap.put(BACKCOLOR, backcolor); + saveMap.put(PAINT, paint); + saveMap.put(BACKPAINT, backPaint); + saveMap.put(LINECAP, new Integer(lineCap)); + saveMap.put(LINEJOIN, new Integer(lineJoin)); + saveMap.put(LINEWIDTH, new Float(lineWidth)); + saveMap.put(MITERLIMIT, new Float(miterLimit)); + saveMap.put(TEXT, new Boolean(text)); + saveMap.put(DASHOFFSET, new Integer(dashOffset)); + saveMap.put(DASHARRAY, dashArray); + saveMap.put(TRANSFORM, transform); + saveMap.put(FONTSIZE, new Float(fontSize)); + saveMap.put(FONTNAME, fontName); + saveMap.put(CLIP, clip); + saveMap.put(GSTATE, gstate); + + stateStack.add(saveMap); + + transform = new AffineTransform(); + } + + /** + * Pop the state from the stack and set current values to popped state. + * This should be called when a Q operator is used so + * the state is restored to the correct values. + */ + public void pop() { + if (getStackLevel() > 0) { + HashMap saveMap = (HashMap)stateStack.get(stateStack.size() - 1); + stateStack.remove(stateStack.size() - 1); + color = (Color)saveMap.get(COLOR); + backcolor = (Color)saveMap.get(BACKCOLOR); + paint = (Paint)saveMap.get(PAINT); + backPaint = (Paint)saveMap.get(BACKPAINT); + lineCap = ((Integer)saveMap.get(LINECAP)).intValue(); + lineJoin = ((Integer)saveMap.get(LINEJOIN)).intValue(); + lineWidth = ((Float)saveMap.get(LINEWIDTH)).floatValue(); + miterLimit = ((Float)saveMap.get(MITERLIMIT)).floatValue(); + text = ((Boolean)saveMap.get(TEXT)).booleanValue(); + dashOffset = ((Integer)saveMap.get(DASHOFFSET)).intValue(); + dashArray = (int[])saveMap.get(DASHARRAY); + transform = (AffineTransform)saveMap.get(TRANSFORM); + fontSize = ((Float)saveMap.get(FONTSIZE)).floatValue(); + fontName = (String)saveMap.get(FONTNAME); + clip = (Shape)saveMap.get(CLIP); + gstate = (PDFGState)saveMap.get(GSTATE); + } + } + + /** + * Get the current stack level. + * + * @return the current stack level + */ + public int getStackLevel() { + return stateStack.size(); + } + + /** + * Restore the state to a particular level. + * this can be used to restore to a known level without making + * multiple pop calls. + * + * @param stack the level to restore to + */ + public void restoreLevel(int stack) { + int pos = stack; + while (stateStack.size() > pos + 1) { + stateStack.remove(stateStack.size() - 1); + } + if (stateStack.size() > pos) { + pop(); + } + } + + /** + * Set the current line dash. + * Check if setting the line dash to the given values + * will make a change and then set the state to the new values. + * + * @param array the line dash array + * @param offset the line dash start offset + * @return true if the line dash has changed + */ + public boolean setLineDash(int[] array, int offset) { + return false; + } + + /** + * Set the current color. + * Check if the new color is a change and then set the current color. + * + * @param col the color to set + * @return true if the color has changed + */ + public boolean setColor(Color col) { + if (!col.equals(color)) { + color = col; + return true; + } + return false; + } + + /** + * Set the current background color. + * Check if the background color will change and then set the new color. + * + * @param col the new background color + * @return true if the background color has changed + */ + public boolean setBackColor(Color col) { + if (!col.equals(backcolor)) { + backcolor = col; + return true; + } + return false; + } + + /** + * Set the current paint. + * This checks if the paint will change and then sets the current paint. + * + * @param p the new paint + * @return true if the new paint changes the current paint + */ + public boolean setPaint(Paint p) { + if (paint == null) { + if (p != null) { + paint = p; + return true; + } + } else if (!paint.equals(p)) { + paint = p; + return true; + } + return false; + } + + /** + * Check if the clip will change the current state. + * A clip is assumed to be used in a situation where it will add + * to any clip in the current or parent states. + * A clip cannot be cleared, this can only be achieved by going to + * a parent level with the correct clip. + * If the clip is different then it may start a new state so that + * it can return to the previous clip. + * + * @param cl the clip shape to check + * @return true if the clip will change the current clip. + */ + public boolean checkClip(Shape cl) { + if (clip == null) { + if (cl != null) { + return true; + } + } else if (!new Area(clip).equals(new Area(cl))) { + return true; + } + // todo check for clips that are larger than the current + return false; + } + + /** + * Set the current clip. + * This either sets a new clip or sets the clip to the intersect of + * the old clip and the new clip. + * + * @param cl the new clip in the current state + */ + public void setClip(Shape cl) { + if (clip != null) { + Area newClip = new Area(clip); + newClip.intersect(new Area(cl)); + clip = new GeneralPath(newClip); + } else { + clip = cl; + } + } + + /** + * Check the current transform. + * The transform for the current state is the combination of all + * transforms in the current state. The parameter is compared + * against this current transform. + * + * @param tf the transform the check against + * @return true if the new transform is different then the current transform + */ + public boolean checkTransform(AffineTransform tf) { + return !tf.equals(transform); + } + + /** + * Set a new transform. + * This transform is appended to the transform of + * the current graphic state. + * + * @param tf the transform to concatonate to the current level transform + */ + public void setTransform(AffineTransform tf) { + transform.concatenate(tf); + } + + /** + * Get the current transform. + * This gets the combination of all transforms in the + * current state. + * + * @return the calculate combined transform for the current state + */ + public AffineTransform getTransform() { + AffineTransform tf; + AffineTransform at = new AffineTransform(); + for (Iterator iter = stateStack.iterator(); iter.hasNext();) { + HashMap map = (HashMap)iter.next(); + tf = (AffineTransform)map.get(TRANSFORM); + at.concatenate(tf); + } + at.concatenate(transform); + + return at; + } + + /** + * Get the grapics state. + * This gets the combination of all graphic states for + * the current context. + * This is the graphic state set with the gs operator not + * the other graphic state changes. + * + * @return the calculated ExtGState in the current context + */ + public PDFGState getGState() { + PDFGState defaultState = PDFGState.DEFAULT; + + PDFGState state; + PDFGState newstate = new PDFGState(0); + newstate.addValues(defaultState); + for (Iterator iter = stateStack.iterator(); iter.hasNext();) { + HashMap map = (HashMap)iter.next(); + state = (PDFGState)map.get(GSTATE); + if (state != null) { + newstate.addValues(state); + } + } + if (gstate != null) { + newstate.addValues(gstate); + } + + return newstate; + } +} + diff --git a/src/java/org/apache/fop/pdf/PDFStream.java b/src/java/org/apache/fop/pdf/PDFStream.java new file mode 100644 index 000000000..b3fbbefe9 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFStream.java @@ -0,0 +1,388 @@ +/* + * $Id: PDFStream.java,v 1.20 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.OutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * Class representing a PDF stream. + *

+ * A derivative of the PDF Object, a PDF Stream has not only a dictionary + * but a stream of PDF commands. The stream of commands is where the real + * work is done, the dictionary just provides information like the stream + * length. + */ +public class PDFStream extends PDFObject { + + /** Key for the default filter */ + public static final String DEFAULT_FILTER = "default"; + /** Key for the filter used for normal content*/ + public static final String CONTENT_FILTER = "content"; + /** Key for the filter used for images */ + public static final String IMAGE_FILTER = "image"; + /** Key for the filter used for JPEG images */ + public static final String JPEG_FILTER = "jpeg"; + /** Key for the filter used for fonts */ + public static final String FONT_FILTER = "font"; + + /** + * The stream of PDF commands + */ + protected StreamCache data; + + /** + * The filters that should be applied + */ + private List filters; + + /** + * Create an empty stream object + * + * @param number the object's number + */ + public PDFStream(int number) { + super(number); + try { + data = StreamCache.createStreamCache(); + } catch (IOException ex) { + /**@todo Log with Logger */ + ex.printStackTrace(); + } + filters = new java.util.ArrayList(); + } + + /** + * Append data to the stream + * + * @param s the string of PDF to add + */ + public void add(String s) { + try { + data.getOutputStream().write(s.getBytes()); + } catch (IOException ex) { + /**@todo Log with Logger */ + ex.printStackTrace(); + } + + } + + /** + * Add a filter for compression of the stream. Filters are + * applied in the order they are added. This should always be a + * new instance of the particular filter of choice. The applied + * flag in the filter is marked true after it has been applied to the + * data. + * @param filter filter to add + */ + public void addFilter(PDFFilter filter) { + if (filter != null) { + filters.add(filter); + } + + } + + /** + * Add a filter for compression of the stream by name. + * @param filterType name of the filter to add + */ + public void addFilter(String filterType) { + if (filterType == null) { + return; + } + if (filterType.equals("flate")) { + addFilter(new FlateFilter()); + } else if (filterType.equals("ascii-85")) { + addFilter(new ASCII85Filter()); + } else if (filterType.equals("ascii-hex")) { + addFilter(new ASCIIHexFilter()); + } else if (filterType.equals("")) { + return; + } else { + throw new IllegalArgumentException( + "Unsupported filter type in stream-filter-list: " + filterType); + } + } + + /** + * Adds the default filters to this stream. + * @param filters Map of filters + * @param type which filter list to modify + */ + public void addDefaultFilters(Map filters, String type) { + List filterset = (List)filters.get(type); + if (filterset == null) { + filterset = (List)filters.get(DEFAULT_FILTER); + } + if (filterset == null || filterset.size() == 0) { + // built-in default to flate + //addFilter(new FlateFilter()); + } else { + for (int i = 0; i < filterset.size(); i++) { + String v = (String)filterset.get(i); + addFilter(v); + } + } + } + + /** + * Append an array of xRGB pixels, ASCII Hex Encoding it first + * + * @param pixels the area of pixels + * @param width the width of the image in pixels + * @param height the height of the image in pixels + */ + public void addImageArray(int[] pixels, int width, int height) { + try { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + int p = pixels[i * width + j]; + int r = (p >> 16) & 0xFF; + int g = (p >> 8) & 0xFF; + int b = (p) & 0xFF; + if (r < 16) { + data.getOutputStream().write('0'); + } + data.getOutputStream().write(Integer.toHexString(r).getBytes()); + if (g < 16) { + data.getOutputStream().write('0'); + } + data.getOutputStream().write(Integer.toHexString(g).getBytes()); + if (b < 16) { + data.getOutputStream().write('0'); + } + data.getOutputStream().write(Integer.toHexString(b).getBytes()); + data.getOutputStream().write(' '); + } + } + data.getOutputStream().write(">\n".getBytes()); + } catch (IOException ex) { + ex.printStackTrace(); + } + + } + + /** + * Used to set the contents of the PDF stream. + * @param data the contents as a byte array + * @throws IOException in case of an I/O problem + */ + public void setData(byte[] data) throws IOException { + this.data.reset(); + this.data.getOutputStream().write(data); + } + + /* + public byte[] getData() { + return _data.toByteArray(); + } + */ + + /** + * Returns the size of the content. + * @return size of the content + */ + public int getDataLength() { + try { + return data.getSize(); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * Represent as PDF. + * + * @return the PDF string. + */ + public byte[] toPDF() { + throw new UnsupportedOperationException("Use output(OutputStream) instead"); + /* + * byte[] d = _data.toByteArray(); + * ByteArrayOutputStream s = new ByteArrayOutputStream(); + * String p = this.number + " " + this.generation + * + " obj\n<< /Length " + (d.length+1) + * + " >>\nstream\n"; + * s.write(p.getBytes()); + * s.write(d); + * s.write("\nendstream\nendobj\n".getBytes()); + * return s.toByteArray(); + */ + } + + /** + * Overload the base object method so we don't have to copy + * byte arrays around so much + * @see org.apache.fop.pdf.PDFObject#output(OutputStream) + */ + protected int output(OutputStream stream) throws IOException { + int length = 0; + String filterEntry = applyFilters(); + byte[] p = (this.number + " " + this.generation + " obj\n<< /Length " + + (data.getSize() + 1) + " " + filterEntry + + " >>\n").getBytes(); + + stream.write(p); + length += p.length; + length += outputStreamData(stream); + p = "endobj\n".getBytes(); + stream.write(p); + length += p.length; + return length; + + } + + /** + * Output just the stream data enclosed by stream/endstream markers + * @param stream OutputStream to write to + * @return int number of bytes written + * @throws IOException in case of an I/O problem + */ + protected int outputStreamData(OutputStream stream) throws IOException { + int length = 0; + byte[] p = "stream\n".getBytes(); + stream.write(p); + length += p.length; + data.outputStreamData(stream); + length += data.getSize(); + data.close(); + p = "\nendstream\n".getBytes(); + stream.write(p); + length += p.length; + return length; + + } + + /** + * Apply the filters to the data + * in the order given and return the /Filter and /DecodeParms + * entries for the stream dictionary. If the filters have already + * been applied to the data (either externally, or internally) + * then the dictionary entries are built and returned. + * @return a String representing the filter list + * @throws IOException in case of an I/O problem + */ + protected String applyFilters() throws IOException { + if (filters.size() > 0) { + List names = new java.util.ArrayList(); + List parms = new java.util.ArrayList(); + + // run the filters + for (int count = 0; count < filters.size(); count++) { + PDFFilter filter = (PDFFilter)filters.get(count); + // apply the filter encoding if neccessary + if (!filter.isApplied()) { + data.applyFilter(filter); + filter.setApplied(true); + } + // place the names in our local vector in reverse order + names.add(0, filter.getName()); + parms.add(0, filter.getDecodeParms()); + } + + // now build up the filter entries for the dictionary + return buildFilterEntries(names) + buildDecodeParms(parms); + } + return ""; + + } + + private String buildFilterEntries(List names) { + StringBuffer sb = new StringBuffer(); + sb.append("/Filter "); + if (names.size() > 1) { + sb.append("[ "); + } + for (int count = 0; count < names.size(); count++) { + sb.append((String)names.get(count)); + sb.append(" "); + } + if (names.size() > 1) { + sb.append("]"); + } + sb.append("\n"); + return sb.toString(); + } + + private String buildDecodeParms(List parms) { + StringBuffer sb = new StringBuffer(); + boolean needParmsEntry = false; + sb.append("/DecodeParms "); + + if (parms.size() > 1) { + sb.append("[ "); + } + for (int count = 0; count < parms.size(); count++) { + String s = (String)parms.get(count); + if (s != null) { + sb.append(s); + needParmsEntry = true; + } else { + sb.append("null"); + } + sb.append(" "); + } + if (parms.size() > 1) { + sb.append("]"); + } + sb.append("\n"); + if (needParmsEntry) { + return sb.toString(); + } else { + return ""; + } + } + + +} diff --git a/src/java/org/apache/fop/pdf/PDFT1Stream.java b/src/java/org/apache/fop/pdf/PDFT1Stream.java new file mode 100644 index 000000000..47a594760 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFT1Stream.java @@ -0,0 +1,129 @@ +/* + * $Id: PDFT1Stream.java,v 1.6 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +// FOP +import org.apache.fop.fonts.type1.PFBData; + +/** + * Special PDFStream for embedding Type 1 fonts. + */ +public class PDFT1Stream extends PDFStream { + + private PFBData pfb; + + /** + * @see org.apache.fop.pdf.PDFObject#PDFObject(int) + */ + public PDFT1Stream(int num) { + super(num); + } + + + /** + * Overload the base object method so we don't have to copy + * byte arrays around so much + * @see org.apache.fop.pdf.PDFObject#output(OutputStream) + */ + protected int output(java.io.OutputStream stream) + throws java.io.IOException { + if (pfb == null) { + throw new IllegalStateException("pfb must not be null at this point"); + } + int length = 0; + String filterEntry = applyFilters(); + String preData = this.number + " " + this.generation + + " obj\n<< /Length " + pfb.getLength() + " " + + filterEntry + + " /Length1 " + pfb.getLength1() + + " /Length2 " + pfb.getLength2() + + " /Length3 " + pfb.getLength3() + " >>\n"; + + byte[] p; + try { + p = preData.getBytes(PDFDocument.ENCODING); + } catch (UnsupportedEncodingException ue) { + p = preData.getBytes(); + } + + stream.write(p); + length += p.length; + + length += outputStreamData(stream); + try { + p = "endobj\n".getBytes(PDFDocument.ENCODING); + } catch (UnsupportedEncodingException ue) { + p = "endobj\n".getBytes(); + } + stream.write(p); + length += p.length; + //System.out.println("Embedded Type1 font"); + return length; + } + + /** + * Used to set the PFBData object that represents the embeddable Type 1 + * font. + * @param pfb The PFB file + * @throws IOException in case of an I/O problem + */ + public void setData(PFBData pfb) throws IOException { + data.reset(); + // System.out.println("Writing " + size + " bytes of font data"); + this.pfb = pfb; + pfb.outputAllParts(data.getOutputStream()); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFTTFStream.java b/src/java/org/apache/fop/pdf/PDFTTFStream.java new file mode 100644 index 000000000..dfab0facc --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFTTFStream.java @@ -0,0 +1,111 @@ +/* + * $Id: PDFTTFStream.java,v 1.5 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.IOException; + +/** + * Special PDFStream for embeddable TrueType fonts. + */ +public class PDFTTFStream extends PDFStream { + + private int origLength; + + /** + * Main constructor + * @param num PDF object number + * @param len original length + */ + public PDFTTFStream(int num, int len) { + super(num); + origLength = len; + } + + /** + * Overload the base object method so we don't have to copy + * byte arrays around so much + * @see org.apache.fop.pdf.PDFObject#output(OutputStream) + */ + protected int output(java.io.OutputStream stream) + throws java.io.IOException { + int length = 0; + String filterEntry = applyFilters(); + String preData = new String(this.number + " " + this.generation + + " obj\n<< /Length " + + (data.getSize() + 1) + " " + filterEntry + + " " + "/Length1 " + origLength + + " >>\n"); + + byte[] p = preData.getBytes(); + stream.write(p); + length += p.length; + + length += outputStreamData(stream); + p = "endobj\n".getBytes(); + stream.write(p); + length += p.length; + return length; + } + + /** + * Sets the TrueType font data. + * @param data the font payload + * @param size size of the payload + * @throws IOException in case of an I/O problem + */ + public void setData(byte[] data, int size) throws IOException { + this.data.reset(); + /**@todo Log using Logger */ + System.out.println("Writing " + size + " bytes of font data"); + this.data.getOutputStream().write(data, 0, size); + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFUri.java b/src/java/org/apache/fop/pdf/PDFUri.java new file mode 100644 index 000000000..9e13cf3af --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFUri.java @@ -0,0 +1,88 @@ +/* + * $Id: PDFUri.java,v 1.5 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +/** + * class used to create a PDF Uri link + */ +public class PDFUri extends PDFAction { + + private String uri; + + /** + * create a Uri instance. + * + * @param uri the uri to which the link should point + */ + public PDFUri(String uri) { + this.uri = uri; + } + + /** + * returns the action ncecessary for a uri + * + * @return the action to place next to /A within a Link + */ + public String getAction() { + return "<< /URI (" + uri + ")\n/S /URI >>"; + } + + /** + * There is nothing to return for the toPDF method + * as it should not be called. + * + * @return an empty array + */ + public byte[] toPDF() { + return new byte[0]; + } + +} diff --git a/src/java/org/apache/fop/pdf/PDFWArray.java b/src/java/org/apache/fop/pdf/PDFWArray.java new file mode 100644 index 000000000..bfc23d7ae --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFWArray.java @@ -0,0 +1,173 @@ +/* + * $Id: PDFWArray.java,v 1.8 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.List; + +/** + * Class representing a W array for CID fonts. + */ +public class PDFWArray { + + /** + * The metrics + */ + private List entries = new java.util.ArrayList(); + + /** + * Default constructor + */ + public PDFWArray() { + } + + /** + * Convenience constructor + * @param metrics the metrics array to initially add + */ + public PDFWArray(int[] metrics) { + addEntry(0, metrics); + } + + /** + * Add an entry for single starting CID. + * i.e. in the form "c [w ...]" + * + * @param start the starting CID value. + * @param metrics the metrics array. + */ + public void addEntry(int start, int[] metrics) { + entries.add(new Entry(start, metrics)); + } + + /** + * Add an entry for a range of CIDs (/W element on p 213) + * + * @param first the first CID in the range + * @param last the last CID in the range + * @param width the width for all CIDs in the range + */ + public void addEntry(int first, int last, int width) { + entries.add(new int[] { + first, last, width + }); + } + + /** + * Add an entry for a range of CIDs (/W2 element on p 210) + * + * @param first the first CID in the range + * @param last the last CID in the range + * @param width the width for all CIDs in the range + * @param posX the x component for the vertical position vector + * @param posY the y component for the vertical position vector + */ + public void addEntry(int first, int last, int width, int posX, int posY) { + entries.add(new int[] { + first, last, width, posX, posY + }); + } + + /** + * Convert this object to PDF code. + * @return byte[] the PDF code + */ + public byte[] toPDF() { + return toPDFString().getBytes(); + } + + /** + * Convert this object to PDF code. + * @return String the PDF code + */ + public String toPDFString() { + StringBuffer p = new StringBuffer(); + p.append("[ "); + int len = entries.size(); + for (int i = 0; i < len; i++) { + Object entry = entries.get(i); + if (entry instanceof int[]) { + int[] line = (int[])entry; + for (int j = 0; j < line.length; j++) { + p.append(line[j]); + p.append(" "); + } + } else { + ((Entry)entry).fillInPDF(p); + } + } + p.append("]"); + return p.toString(); + } + + /** + * Inner class for entries in the form "c [w ...]" + */ + private static class Entry { + private int start; + private int[] metrics; + public Entry(int s, int[] m) { + start = s; + metrics = m; + } + + public void fillInPDF(StringBuffer p) { + // p.setLength(0); + p.append(start); + p.append(" ["); + for (int i = 0; i < metrics.length; i++) { + p.append(this.metrics[i]); + p.append(" "); + } + p.append("] "); + } + + } +} diff --git a/src/java/org/apache/fop/pdf/PDFXObject.java b/src/java/org/apache/fop/pdf/PDFXObject.java new file mode 100644 index 000000000..94dabac25 --- /dev/null +++ b/src/java/org/apache/fop/pdf/PDFXObject.java @@ -0,0 +1,213 @@ +/* + * $Id: PDFXObject.java,v 1.22 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +// Java +import java.io.IOException; +import java.io.OutputStream; + +/* modified by JKT to integrate with 0.12.0 */ +/* modified by Eric SCHAEFFER to integrate with 0.13.0 */ + +/** + * PDF XObject + * + * A derivative of the PDF Object, is a PDF Stream that has not only a + * dictionary but a stream of image data. + * The dictionary just provides information like the stream length. + * This outputs the image dictionary and the image data. + * This is used as a reference for inserting the same image in the + * document in another place. + */ +public class PDFXObject extends PDFObject { + private PDFImage pdfimage; + private int xnum; + + /** + * create an XObject with the given number and name and load the + * image in the object + * + * @param number the pdf object number + * @param xnumber the pdf object X number + * @param img the pdf image that contains the image data + */ + public PDFXObject(int number, int xnumber, PDFImage img) { + super(number); + this.xnum = xnumber; + pdfimage = img; + } + + /** + * Get the xnumber for this pdf object. + * + * @return the PDF XObject number + */ + public int getXNumber() { + return this.xnum; + } + + /** + * Output the image as PDF. + * This sets up the image dictionary and adds the image data stream. + * + * @param stream the output stream to write the data + * @throws IOException if there is an error writing the data + * @return the length of the data written + */ + protected int output(OutputStream stream) throws IOException { + int length = 0; + int i = 0; + + if (pdfimage.isPS()) { + length = outputEPSImage(stream); + } else { + + PDFStream imgStream = pdfimage.getDataStream(); + + String dictEntries = imgStream.applyFilters(); + + String p = this.number + " " + this.generation + " obj\n"; + p = p + "<>\n"; + + // push the pdf dictionary on the writer + byte[] pdfBytes = p.getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // push all the image data on the writer + // and takes care of length for trailer + length += imgStream.outputStreamData(stream); + + pdfBytes = ("endobj\n").getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + } + // let it gc + // this object is retained as a reference to inserting + // the same image but the image data is no longer needed + pdfimage = null; + return length; + } + + byte[] toPDF() { + return null; + } + + private int outputEPSImage(OutputStream stream) throws IOException { + int length = 0; + int i = 0; + + PDFStream imgStream = pdfimage.getDataStream(); + String dictEntries = imgStream.applyFilters(); + + String p = this.number + " " + this.generation + " obj\n"; + p = p + "<>\n"; + + // push the pdf dictionary on the writer + byte[] pdfBytes = p.getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + // push all the image data on the writer and takes care of length for trailer + length += imgStream.outputStreamData(stream); + + pdfBytes = ("endobj\n").getBytes(); + stream.write(pdfBytes); + length += pdfBytes.length; + + return length; + } + +} diff --git a/src/java/org/apache/fop/pdf/StreamCache.java b/src/java/org/apache/fop/pdf/StreamCache.java new file mode 100644 index 000000000..5eb73b9e8 --- /dev/null +++ b/src/java/org/apache/fop/pdf/StreamCache.java @@ -0,0 +1,149 @@ +/* + * $Id: StreamCache.java,v 1.3 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.io.OutputStream; +import java.io.IOException; + +/** + * class used to store the bytes for a PDFStream. It's actually a generic + * cached byte array, along with a factory that returns either an + * in-memory or tempfile based implementation based on the global + * cacheToFile setting. + */ +public abstract class StreamCache { + + /** + * Global setting; controls whether to use tempfiles or not. + */ + private static boolean cacheToFile = false; + + /** + * Change the global cacheToFile flag. + * + * @param tizit true if cache to file + */ + public static void setCacheToFile(boolean tizit) { + cacheToFile = tizit; + } + + /** + * Get the value of the global cacheToFile flag. + * + * @return the current cache to file flag + */ + public static boolean getCacheToFile() { + return cacheToFile; + } + + /** + * Get the correct implementation (based on cacheToFile) of + * StreamCache. + * + * @throws IOException if there is an IO error + * @return a new StreamCache for caching streams + */ + public static StreamCache createStreamCache() throws IOException { + if (cacheToFile) { + return new TempFileStreamCache(); + } else { + return new InMemoryStreamCache(); + } + } + + /** + * Get the current OutputStream. Do not store it - it may change + * from call to call. + * + * @throws IOException if there is an IO error + * @return an output stream for this cache + */ + public abstract OutputStream getOutputStream() throws IOException; + + /** + * Filter the cache with the supplied PDFFilter. + * + * @param filter the filter to apply + * @throws IOException if there is an IO error + */ + public abstract void applyFilter(PDFFilter filter) throws IOException; + + /** + * Outputs the cached bytes to the given stream. + * + * @param stream the stream to write to + * @throws IOException if there is an IO error + */ + public abstract void outputStreamData(OutputStream stream) throws IOException; + + /** + * Returns the current size of the stream. + * + * @throws IOException if there is an IO error + * @return the size of the cache + */ + public abstract int getSize() throws IOException; + + /** + * Closes the cache and frees resources. + * + * @throws IOException if there is an IO error + */ + public abstract void close() throws IOException; + + /** + * Clears and resets the cache. + * + * @throws IOException if there is an IO error + */ + public abstract void reset() throws IOException; +} + diff --git a/src/java/org/apache/fop/pdf/TempFileStreamCache.java b/src/java/org/apache/fop/pdf/TempFileStreamCache.java new file mode 100644 index 000000000..3c23bb9c4 --- /dev/null +++ b/src/java/org/apache/fop/pdf/TempFileStreamCache.java @@ -0,0 +1,198 @@ +/* + * $Id: TempFileStreamCache.java,v 1.3 2003/03/07 08:25:46 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import org.apache.fop.util.StreamUtilities; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.io.File; + +/** + * StreamCache implementation that uses temporary files rather than heap. + */ +public class TempFileStreamCache extends StreamCache { + + /** + * The current output stream. + */ + private BufferedOutputStream output; + + /** + * The temp file. + */ + private File tempFile; + + /** + * Creates a new TempFileStreamCache. + * + * @throws IOException if there is an IO error + */ + public TempFileStreamCache() throws IOException { + tempFile = File.createTempFile("org.apache.fop.pdf.StreamCache-", + ".temp"); + tempFile.deleteOnExit(); + } + + /** + * Get the current OutputStream. Do not store it - it may change + * from call to call. + * + * @throws IOException if there is an IO error + * @return the output stream for this cache + */ + public OutputStream getOutputStream() throws IOException { + if (output == null) { + output = new BufferedOutputStream( + new FileOutputStream(tempFile)); + } + return output; + } + + /** + * Filter the cache with the supplied PDFFilter. + * + * @param filter the filter to apply + * @throws IOException if there is an IO error + */ + public void applyFilter(PDFFilter filter) throws IOException { + if (output == null) { + return; + } + + output.close(); + output = null; + + // need a place to put results + File newTempFile = + File.createTempFile("org.apache.fop.pdf.StreamCache-", + ".temp"); + newTempFile.deleteOnExit(); + + // filter may not be buffered + BufferedInputStream input = + new BufferedInputStream(new FileInputStream(tempFile)); + BufferedOutputStream output = new BufferedOutputStream( + new FileOutputStream(newTempFile)); + filter.encode(input, output, (int) tempFile.length()); + input.close(); + output.close(); + tempFile.delete(); + tempFile = newTempFile; + } + + /** + * Outputs the cached bytes to the given stream. + * + * @param stream the output stream to write to + * @throws IOException if there is an IO error + */ + public void outputStreamData(OutputStream stream) throws IOException { + if (output == null) { + return; + } + + output.close(); + output = null; + + // don't need a buffer because streamCopy is buffered + FileInputStream input = new FileInputStream(tempFile); + StreamUtilities.streamCopy(input, output); + input.close(); + } + + /** + * Returns the current size of the stream. + * + * @throws IOException if there is an IO error + * @return the size of the cache + */ + public int getSize() throws IOException { + if (output != null) { + output.flush(); + } + return (int) tempFile.length(); + } + + /** + * Closes the cache and frees resources. + * + * @throws IOException if there is an IO error + */ + public void close() throws IOException { + if (output != null) { + output.close(); + output = null; + } + if (tempFile.exists()) { + tempFile.delete(); + } + } + + /** + * Clears and resets the cache. + * + * @throws IOException if there is an IO error + */ + public void reset() throws IOException { + if (output != null) { + output.close(); + output = null; + } + if (tempFile.exists()) { + tempFile.delete(); + } + } +} diff --git a/src/java/org/apache/fop/pdf/TransitionDictionary.java b/src/java/org/apache/fop/pdf/TransitionDictionary.java new file mode 100644 index 000000000..16de50b3e --- /dev/null +++ b/src/java/org/apache/fop/pdf/TransitionDictionary.java @@ -0,0 +1,99 @@ +/* + * $Id: TransitionDictionary.java,v 1.3 2003/03/07 08:25:47 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.pdf; + +import java.util.Map; +import java.util.Iterator; + +/** + * Transition Dictionary + * This class is used to build a transition dictionary to + * specify the transition between pages. + */ +public class TransitionDictionary extends PDFObject { + + private Map dictionaryValues; + + /** + * Create a Transition Dictionary + * + * @param values the dictionary values to output + */ + public TransitionDictionary(Map values) { + dictionaryValues = values; + } + + /** + * Get the dictionary. + * This returns the string containing the dictionary values. + * + * @return the string with the dictionary values + */ + public String getDictionary() { + StringBuffer sb = new StringBuffer(); + sb.append("/Type /Trans\n"); + for (Iterator iter = dictionaryValues.keySet().iterator(); iter.hasNext();) { + Object key = iter.next(); + sb.append(key + " " + dictionaryValues.get(key) + "\n"); + } + return sb.toString(); + } + + /** + * there is nothing to return for the toPDF method, as it should not be called + * + * @return an empty string + */ + public byte[] toPDF() { + return new byte[0]; + } +} + diff --git a/src/java/org/apache/fop/pdf/package.html b/src/java/org/apache/fop/pdf/package.html new file mode 100644 index 000000000..1fd09411d --- /dev/null +++ b/src/java/org/apache/fop/pdf/package.html @@ -0,0 +1,8 @@ + +org.apache.fop.pdf Package + +

Classes for handling the low-level creation of PDF documents

+

These classes were developed for FOP, but could be used by other +applications wishing to produce PDF.

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java new file mode 100644 index 000000000..65cab8d6b --- /dev/null +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -0,0 +1,654 @@ +/* + * $Id: AbstractRenderer.java,v 1.31 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render; + +// Java +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.Map; +import java.util.List; +import java.util.Iterator; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.area.Area; +import org.apache.fop.area.BeforeFloat; +import org.apache.fop.area.Block; +import org.apache.fop.area.BlockViewport; +import org.apache.fop.area.BodyRegion; +import org.apache.fop.area.CTM; +import org.apache.fop.area.Flow; +import org.apache.fop.area.Footnote; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.MainReference; +import org.apache.fop.area.Span; +import org.apache.fop.area.Page; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.Title; +import org.apache.fop.area.TreeExt; +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; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.Word; +import org.apache.fop.area.inline.Character; + +// Avalon +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.configuration.Configurable; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; + +/** + * Abstract base class for all renderers. The Abstract renderer does all the + * top level processing of the area tree and adds some abstract methods to + * handle viewports. This keeps track of the current block and inline position. + */ +public abstract class AbstractRenderer extends AbstractLogEnabled + implements Renderer, Configurable { + + /** + * user agent + */ + protected FOUserAgent userAgent; + + /** + * renderer configuration + */ + protected Map options; + + /** + * block progression position + */ + protected int currentBPPosition = 0; + + /** + * inline progression position + */ + protected int currentIPPosition = 0; + + /** + * current inline progression position in block + */ + protected int currentBlockIPPosition = 0; + + /** + * the block progression position of the containing block used for + * absolutely positioned blocks + */ + protected int containingBPPosition = 0; + + /** + * the inline progression position of the containing block used for + * absolutely positioned blocks + */ + protected int containingIPPosition = 0; + + /** + * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) + */ + public void configure(Configuration conf) throws ConfigurationException { + } + + /** @see org.apache.fop.render.Renderer */ + public void setProducer(String producer) { + } + + /** @see org.apache.fop.render.Renderer */ + public void setCreator(String creator) { + } + + /** @see org.apache.fop.render.Renderer */ + public void setUserAgent(FOUserAgent agent) { + userAgent = agent; + } + + /** @see org.apache.fop.render.Renderer */ + public void setOptions(Map opt) { + options = opt; + } + + /** + * Check if this renderer supports out of order rendering. If this renderer + * supports out of order rendering then it means that the pages that are + * not ready will be prepared and a future page will be rendered. + * + * @return True if the renderer supports out of order rendering + * @see org.apache.fop.render.Renderer + */ + public boolean supportsOutOfOrder() { + return false; + } + + /** + * @param ext @todo Description of the Parameter + * @see org.apache.fop.render.Renderer + */ + public void renderExtension(TreeExt ext) { } + + /** + * Prepare a page for rendering. This is called if the renderer supports + * out of order rendering. The renderer should prepare the page so that a + * page further on in the set of pages can be rendered. The body of the + * page should not be rendered. The page will be rendered at a later time + * by the call to render page. + * + * @see org.apache.fop.render.Renderer + */ + public void preparePage(PageViewport page) { } + + /** + * Utility method to convert a page sequence title to a string. Some + * renderers may only be able to use a string title. A title is a sequence + * of inline areas that this method attempts to convert to an equivalent + * string. + * + * @param title The Title to convert + * @return An expanded string representing the title + */ + protected String convertTitleToString(Title title) { + List children = title.getInlineAreas(); + String str = convertToString(children); + return str.trim(); + } + + private String convertToString(List children) { + StringBuffer sb = new StringBuffer(); + for (int count = 0; count < children.size(); count++) { + InlineArea inline = (InlineArea) children.get(count); + if (inline instanceof Character) { + sb.append(((Character) inline).getChar()); + } else if (inline instanceof Word) { + sb.append(((Word) inline).getWord()); + } else if (inline instanceof InlineParent) { + sb.append(convertToString( + ((InlineParent) inline).getChildAreas())); + } else { + sb.append(" "); + } + } + return sb.toString(); + } + + /** @see org.apache.fop.render.Renderer */ + public void startPageSequence(Title seqTitle) { + //do nothing + } + + // normally this would be overriden to create a page in the + // output + /** @see org.apache.fop.render.Renderer */ + public void renderPage(PageViewport page) + throws IOException, FOPException { + + Page p = page.getPage(); + renderPageAreas(p); + } + + /** + * Renders page areas. + * + * @param page The page whos page areas are to be rendered + */ + protected void renderPageAreas(Page page) { + RegionViewport viewport; + viewport = page.getRegion(RegionReference.BEFORE); + renderRegionViewport(viewport); + viewport = page.getRegion(RegionReference.START); + renderRegionViewport(viewport); + viewport = page.getRegion(RegionReference.BODY); + renderRegionViewport(viewport); + viewport = page.getRegion(RegionReference.END); + renderRegionViewport(viewport); + viewport = page.getRegion(RegionReference.AFTER); + renderRegionViewport(viewport); + } + + /** + * Renders a region viewport.

+ * + * The region may clip the area and it establishes a position from where + * the region is placed.

+ * + * @param port The region viewport to be rendered + */ + protected void renderRegionViewport(RegionViewport port) { + if (port != null) { + Rectangle2D view = port.getViewArea(); + // The CTM will transform coordinates relative to + // this region-reference area into page coords, so + // set origin for the region to 0,0. + currentBPPosition = 0; + currentIPPosition = 0; + currentBlockIPPosition = currentIPPosition; + + RegionReference region = port.getRegion(); + // shouldn't the viewport have the CTM + startVParea(region.getCTM()); + + // do after starting viewport area + handleViewportTraits(port); + if (region.getRegionClass() == RegionReference.BODY) { + renderBodyRegion((BodyRegion) region); + } else { + renderRegion(region); + } + endVParea(); + } + } + + /** + * @todo Description of the Method + * + * @param ctm The coordinate transformation matrix to use + */ + protected void startVParea(CTM ctm) { } + + /** + * Handle viewport traits. + * This should be overridden to draw border and background + * traits for the viewport area. + * + * @param rv the region viewport area + */ + protected void handleViewportTraits(RegionViewport rv) { + // draw border and background + } + + /** + * @todo Description of the Method + */ + protected void endVParea() { } + + /** + * Renders a region reference area. + * + * @param region The region reference area + */ + protected void renderRegion(RegionReference region) { + List blocks = region.getBlocks(); + + renderBlocks(blocks); + + } + + /** + * Renders a body region area. + * + * @param region The body region + */ + protected void renderBodyRegion(BodyRegion region) { + BeforeFloat bf = region.getBeforeFloat(); + if (bf != null) { + renderBeforeFloat(bf); + } + MainReference mr = region.getMainReference(); + if (mr != null) { + renderMainReference(mr); + } + Footnote foot = region.getFootnote(); + if (foot != null) { + renderFootnote(foot); + } + } + + /** + * Renders a before float area. + * + * @param bf The before float area + */ + protected void renderBeforeFloat(BeforeFloat bf) { + List blocks = bf.getChildAreas(); + if (blocks != null) { + renderBlocks(blocks); + Block sep = bf.getSeparator(); + if (sep != null) { + renderBlock(sep); + } + } + } + + /** + * Renders a footnote + * + * @param footnote The footnote + */ + protected void renderFootnote(Footnote footnote) { + List blocks = footnote.getChildAreas(); + if (blocks != null) { + Block sep = footnote.getSeparator(); + if (sep != null) { + renderBlock(sep); + } + renderBlocks(blocks); + } + } + + /** + * Renders the main reference area. + *

+ * The main reference area contains a list of spans that are + * stacked on the page. + * The spans contain a list of normal flow reference areas + * that are positioned into columns. + *

+ * + * @param mr The main reference area + */ + protected void renderMainReference(MainReference mr) { + int saveIPPos = currentIPPosition; + + Span span = null; + List spans = mr.getSpans(); + for (int count = 0; count < spans.size(); count++) { + span = (Span) spans.get(count); + int offset = (mr.getWidth() + - (span.getColumnCount() - 1) * mr.getColumnGap()) + / span.getColumnCount() + mr.getColumnGap(); + for (int c = 0; c < span.getColumnCount(); c++) { + Flow flow = (Flow) span.getFlow(c); + + renderFlow(flow); + currentIPPosition += offset; + } + currentIPPosition = saveIPPos; + currentBPPosition += span.getHeight(); + } + } + + /** + * Renders a flow reference area. + * + * @param flow The flow reference area + */ + protected void renderFlow(Flow flow) { + // the normal flow reference area contains stacked blocks + List blocks = flow.getChildAreas(); + if (blocks != null) { + renderBlocks(blocks); + } + } + + /** + * Renders a block area. + * + * @param block The block area + */ + protected void renderBlock(Block block) { + List children = block.getChildAreas(); + if (children == null) { + handleBlockTraits(block); + // simply move position + currentBPPosition += block.getHeight(); + } else if (block instanceof BlockViewport) { + renderBlockViewport((BlockViewport) block, children); + } else { + // save position and offset + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + if (block.getPositioning() == Block.ABSOLUTE) { + currentIPPosition = containingIPPosition + block.getXOffset(); + currentBPPosition = containingBPPosition + block.getYOffset(); + + handleBlockTraits(block); + + renderBlocks(children); + + // absolute blocks do not effect the layout + currentBPPosition = saveBP; + } else { + // relative blocks are offset + currentIPPosition += block.getXOffset(); + currentBPPosition += block.getYOffset(); + + handleBlockTraits(block); + + renderBlocks(children); + + // stacked and relative blocks effect stacking + currentBPPosition = saveBP + block.getHeight(); + } + currentIPPosition = saveIP; + } + } + + /** + * Handle block traits. + * This method is called when the correct ip and bp posiiton is + * set. This should be overridden to draw border and background + * traits for the block area. + * + * @param block the block area + */ + protected void handleBlockTraits(Block block) { + // draw border and background + } + + /** + * Renders a block viewport. + * + * @param bv The block viewport + * @param children The children to render within the block viewport + */ + protected void renderBlockViewport(BlockViewport bv, List children) { + // clip and position viewport if necessary + if (bv.getPositioning() == Block.ABSOLUTE) { + // save positions + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + + CTM ctm = bv.getCTM(); + currentIPPosition = 0; + currentBPPosition = 0; + + startVParea(ctm); + handleBlockTraits(bv); + renderBlocks(children); + endVParea(); + + // clip if necessary + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } else { + renderBlocks(children); + } + } + + /** + * Renders a line area.

+ * + * A line area may have grouped styling for its children such as underline, + * background.

+ * + * @param line The line area + */ + protected void renderLineArea(LineArea line) { + List children = line.getInlineAreas(); + + for (int count = 0; count < children.size(); count++) { + InlineArea inline = (InlineArea) children.get(count); + inline.render(this); + } + } + + /** @see org.apache.fop.render.Renderer */ + public void renderViewport(Viewport viewport) { + Area content = viewport.getContent(); + int saveBP = currentBPPosition; + currentBPPosition += viewport.getOffset(); + Rectangle2D contpos = viewport.getContentPosition(); + if (content instanceof Image) { + renderImage((Image) content, contpos); + } else if (content instanceof Container) { + renderContainer((Container) content); + } else if (content instanceof ForeignObject) { + renderForeignObject((ForeignObject) content, contpos); + } + currentBlockIPPosition += viewport.getWidth(); + currentBPPosition = saveBP; + } + + /** + * Renders an image area. + * + * @param image The image + * @param pos The target position of the image + * @todo Make renderImage() protected + */ + public void renderImage(Image image, Rectangle2D pos) { + // Default: do nothing. + // Some renderers (ex. Text) don't support images. + } + + /** @see org.apache.fop.render.Renderer */ + public void renderContainer(Container cont) { + int saveIP = currentIPPosition; + currentIPPosition = currentBlockIPPosition; + int saveBlockIP = currentBlockIPPosition; + int saveBP = currentBPPosition; + + List blocks = cont.getBlocks(); + renderBlocks(blocks); + currentIPPosition = saveIP; + currentBlockIPPosition = saveBlockIP; + currentBPPosition = saveBP; + } + + /** + * Renders a foreign object area. + * + * @param fo The foreign object area + * @param pos The target position of the foreign object + * @todo Make renderForeignObject() protected + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + // Default: do nothing. + // Some renderers (ex. Text) don't support foreign objects. + } + + /** @see org.apache.fop.render.Renderer */ + public void renderCharacter(Character ch) { + currentBlockIPPosition += ch.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + public void renderInlineSpace(Space space) { + // an inline space moves the inline progression position + // for the current block by the width or height of the space + // it may also have styling (only on this object) that needs + // handling + currentBlockIPPosition += space.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + public void renderLeader(Leader area) { + currentBlockIPPosition += area.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + public void renderWord(Word word) { + currentBlockIPPosition += word.getWidth(); + } + + /** @see org.apache.fop.render.Renderer */ + public void renderInlineParent(InlineParent ip) { + int saveIP = currentBlockIPPosition; + Iterator iter = ip.getChildAreas().iterator(); + while (iter.hasNext()) { + ((InlineArea) iter.next()).render(this); + } + currentBlockIPPosition = saveIP + ip.getWidth(); + } + + /** + * Renders a list of block areas. + * + * @param blocks The block areas + */ + protected void renderBlocks(List blocks) { + // the position of the containing block is used for + // absolutely positioned areas + int contBP = currentBPPosition; + int contIP = currentIPPosition; + containingBPPosition = contBP; + containingIPPosition = contIP; + + for (int count = 0; count < blocks.size(); count++) { + Object obj = blocks.get(count); + if (obj instanceof Block) { + containingBPPosition = contBP; + containingIPPosition = contIP; + renderBlock((Block) obj); + containingBPPosition = contBP; + containingIPPosition = contIP; + } else { + // a line area is rendered from the top left position + // of the line, each inline object is offset from there + LineArea line = (LineArea) obj; + currentBlockIPPosition = + currentIPPosition + line.getStartIndent(); + renderLineArea(line); + currentBPPosition += line.getHeight(); + } + } + } + +} + diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java new file mode 100644 index 000000000..ad21c38be --- /dev/null +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -0,0 +1,89 @@ +/* + * $Id: PrintRenderer.java,v 1.21 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render; + +// FOP +import org.apache.fop.render.pdf.FontSetup; +import org.apache.fop.layout.FontInfo; + +// Java +import java.util.List; +import java.io.IOException; +import java.io.OutputStream; + +/** Abstract base class of "Print" type renderers. */ +public abstract class PrintRenderer extends AbstractRenderer { + + /** Font configuration */ + protected FontInfo fontInfo; + + /** list of fonts */ + protected List fontList = null; + + /** + * Set up the font info + * + * @param fontInfo font info to set up + */ + public void setupFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + FontSetup.setup(fontInfo, fontList); + } + + /** @see org.apache.fop.render.Renderer */ + public void startRenderer(OutputStream outputStream) + throws IOException { } + + /** @see org.apache.fop.render.Renderer */ + public void stopRenderer() + throws IOException { } + +} diff --git a/src/java/org/apache/fop/render/Renderer.java b/src/java/org/apache/fop/render/Renderer.java new file mode 100644 index 000000000..d096c3381 --- /dev/null +++ b/src/java/org/apache/fop/render/Renderer.java @@ -0,0 +1,255 @@ +/* + * $Id: Renderer.java,v 1.31 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render; + +// Java +import java.io.OutputStream; +import java.io.IOException; +import java.util.Map; + +// FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Title; +import org.apache.fop.area.TreeExt; +import org.apache.fop.area.inline.Container; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.Word; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.fo.FOUserAgent; + +/** + * Interface implemented by all renderers. This interface is used to control + * the rendering of pages and to let block and inline level areas call the + * appropriate method to render themselves.

+ * + * A Renderer implementation takes areas/spaces and produces output in some + * format.

+ * + * Typically, most renderers are subclassed from FOP's abstract implementations + * ({@link AbstractRenderer}, {@link PrintRenderer}) which already handle a lot + * of things letting you concentrate on the details of the output format. + */ +public interface Renderer { + + /** + * Role constant for Avalon. + */ + String ROLE = Renderer.class.getName(); + + + /** + * Initiates the rendering phase. + * This must only be called once for a rendering. If + * stopRenderer is called then this may be called again + * for a new document rendering. + * + * @param outputStream The OutputStream to use for output + * @exception IOException If an I/O error occurs + */ + void startRenderer(OutputStream outputStream) + throws IOException; + + /** + * Signals the end of the rendering phase. + * The renderer should reset to an initial state and dispose of + * any resources for the completed rendering. + * + * @exception IOException If an I/O error occurs + */ + void stopRenderer() + throws IOException; + + /** + * Set the User Agent. + * + * @param agent The User Agent + */ + void setUserAgent(FOUserAgent agent); + + /** + * Set up the given FontInfo. + * + * @param fontInfo The fonts + */ + void setupFontInfo(FontInfo fontInfo); + + /** + * Set up renderer options. + * + * @param options The Configuration for the renderer + */ + void setOptions(Map options); + + /** + * Set the producer of the rendering. If this method isn't called the + * renderer uses a default. Note: Not all renderers support this feature. + * + * @param producer The name of the producer (normally "FOP") to be + * embedded in the generated file. + */ + void setProducer(String producer); + + /** + * Set the creator of the document to be rendered. If this method + * isn't called the renderer uses a default. + * Note: Not all renderers support this feature. + * + * @param creator The name of the document creator + */ + void setCreator(String creator); + + /** + * Reports if out of order rendering is supported.

+ * + * Normally, all pages of a document are rendered in their natural order + * (page 1, page 2, page 3 etc.). Some output formats (such as PDF) allow + * pages to be output in random order. This is helpful to reduce resource + * strain on the system because a page that cannot be fully resolved + * doesn't block subsequent pages that are already fully resolved.

+ * + * @return True if this renderer supports out of order rendering. + */ + boolean supportsOutOfOrder(); + + /** + * Tells the renderer to render an extension element. + * + * @param ext The extension element to be rendered + */ + void renderExtension(TreeExt ext); + + /** + * This is called if the renderer supports out of order rendering. The + * renderer should prepare the page so that a page further on in the set of + * pages can be rendered. The body of the page should not be rendered. The + * page will be rendered at a later time by the call to {@link + * #renderPage(PageViewport)}. + * + * @param page The page viewport to use + */ + void preparePage(PageViewport page); + + /** + * Tells the renderer that a new page sequence starts. + * + * @param seqTitle The title of the page sequence + */ + void startPageSequence(Title seqTitle); + + /** + * Tells the renderer to render a particular page. A renderer typically + * reponds by packing up the current page and writing it immediately to the + * output device. + * + * @param page The page to be rendered + * @exception IOException if an I/O error occurs + * @exception FOPException if a FOP interal error occurs. + */ + void renderPage(PageViewport page) + throws IOException, FOPException; + + /** + * Tells the renderer to render an inline viewport. It sets up clipping as + * necessary. + * + * @param viewport The viewport area + */ + void renderViewport(Viewport viewport); + + /** + * Tells the renderer to render an inline container. + * + * @param cont The inline container area + */ + void renderContainer(Container cont); + + /** + * Tells the renderer to render an inline word. + * + * @param area The word area + */ + void renderWord(Word area); + + /** + * Tells the renderer to render an inline parent area. + * + * @param ip The inline parent area + */ + void renderInlineParent(InlineParent ip); + + /** + * Tells the renderer to render an inline character. + * + * @param ch The inline character + */ + void renderCharacter( + org.apache.fop.area.inline.Character ch); + + /** + * Tells the renderer to render an inline space. + * + * @param space The inline space + */ + void renderInlineSpace(Space space); + + /** + * Tells the renderer to render an inline leader area. + * + * @param area The inline leader area. + */ + void renderLeader(Leader area); + +} + diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java new file mode 100644 index 000000000..4ffbd2297 --- /dev/null +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -0,0 +1,127 @@ +/* + * $Id: RendererContext.java,v 1.6 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render; + +//Java +import java.util.Map; + +//FOP +import org.apache.fop.fo.FOUserAgent; + +/** + * The Render Context for external handlers. This provides a rendering context + * so that external handlers can get information to be able to render to the + * render target. + */ +public class RendererContext { + + private String mime; + private FOUserAgent userAgent; + private Map props = new java.util.HashMap(); + + /** + * Contructor for this class. It takes a MIME type as parameter. + * + * @param m The MIME type of the output that's generated. + */ + public RendererContext(String m) { + mime = m; + } + + /** + * Returns the MIME type associated with this RendererContext. + * + * @return The MIME type (ex. application/pdf) + */ + public String getMimeType() { + return mime; + } + + /** + * Sets the user agent. + * + * @param ua The user agent + */ + public void setUserAgent(FOUserAgent ua) { + userAgent = ua; + } + + /** + * Returns the user agent. + * + * @return The user agent + */ + public FOUserAgent getUserAgent() { + return userAgent; + } + + /** + * Sets a property on the RendererContext. + * + * @param name The key of the property + * @param val The value of the property + */ + public void setProperty(String name, Object val) { + props.put(name, val); + } + + /** + * Returns a property from the RendererContext. + * + * @param prop The key of the property to return. + * @return The requested value, null if it doesn't exist. + */ + public Object getProperty(String prop) { + return props.get(prop); + } + +} + diff --git a/src/java/org/apache/fop/render/XMLHandler.java b/src/java/org/apache/fop/render/XMLHandler.java new file mode 100644 index 000000000..6a4ccd158 --- /dev/null +++ b/src/java/org/apache/fop/render/XMLHandler.java @@ -0,0 +1,77 @@ +/* + * $Id: XMLHandler.java,v 1.4 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render; + +import org.w3c.dom.Document; + +/** + * This interface is implemented by classes that can handle a certain type + * of foreign objects. + */ +public interface XMLHandler { + + /** + * Handle an external xml document inside a Foreign Object Area.

+ * + * This may throw an exception if for some reason it cannot be handled. The + * caller is expected to deal with this exception.

+ * + * @param context The RendererContext (contains the user agent) + * @param doc A DOM containing the foreign object to be + * processed + * @param ns The Namespace of the foreign object + * @exception Exception If an error occurs during processing. + */ + void handleXML(RendererContext context, Document doc, String ns) + throws Exception; + +} + diff --git a/src/java/org/apache/fop/render/awt/AWTFontMetrics.java b/src/java/org/apache/fop/render/awt/AWTFontMetrics.java new file mode 100644 index 000000000..08c7301de --- /dev/null +++ b/src/java/org/apache/fop/render/awt/AWTFontMetrics.java @@ -0,0 +1,315 @@ +/* + * $Id: AWTFontMetrics.java,v 1.6 2003/03/07 09:46:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.awt; + +// Java +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.FontMetrics; +import java.awt.font.TextLayout; + +/** + * This is a FontMetrics to be used for AWT rendering. + * It instanciates a font, depening on family and style + * values. The java.awt.FontMetrics for this font is then + * created to be used for the actual measurement. + * Since layout is word by word and since it is expected that + * two subsequent words often share the same style, the + * Font and FontMetrics is buffered and only changed if needed. + *

+ * Since FontState and FontInfo multiply all factors by + * size, we assume a "standard" font of FONT_SIZE. + */ +public class AWTFontMetrics { + + /** + * Font size standard used for metric measurements + */ + public static final int FONT_SIZE = 1; + + /** + * This factor multiplies the calculated values to scale + * to FOP internal measurements + */ + public static final int FONT_FACTOR = (1000 * 1000) / FONT_SIZE; + + /** + * The width of all 256 character, if requested + */ + private int width[] = null; + + /** + * The typical height of a small cap latter + */ + private int xHeight = 0; + + /** + * Buffered font. + * f1 is bufferd for metric measurements during layout. + * fSized is buffered for display purposes + */ + private Font f1 = null; // , fSized = null; + + /** + * The family type of the font last used + */ + private String family = ""; + + /** + * The style of the font last used + */ + private int style = 0; + + /** + * The size of the font last used + */ + private float size = 0; + + /** + * The FontMetrics object used to calculate character width etc. + */ + private FontMetrics fmt = null; + + /** + * Temp graphics object needed to get the font metrics + */ + private Graphics2D graphics; + + /** + * Constructs a new Font-metrics. + * @param graphics a temp graphics object - this is needed so + * that we can get an instance of java.awt.FontMetrics + */ + public AWTFontMetrics(Graphics2D graphics) { + this.graphics = graphics; + } + + /** + * Determines the font ascent of the Font described by this + * FontMetrics object + * @param family font family (java name) to use + * @param style font style (java def.) to use + * @param size font size + * @return ascent in milliponts + */ + public int getAscender(String family, int style, int size) { + setFont(family, style, size); + // return (int)(FONT_FACTOR * fmt.getAscent()); + + // workaround for sun bug on FontMetrics.getAscent() + // http://developer.java.sun.com/developer/bugParade/bugs/4399887.html + int realAscent = fmt.getAscent() + - (fmt.getDescent() + fmt.getLeading()); + return FONT_FACTOR * realAscent; + } + + + /** + * The size of a capital letter measured from the font's baseline + * @param family font family + * @param style font style + * @param size font size + * @return capital height in millipoints + */ + public int getCapHeight(String family, int style, int size) { + // currently just gets Ascent value but maybe should use + // getMaxAcent() at some stage + return getAscender(family, style, size); + } + + /** + * Determines the font descent of the Font described by this + * FontMetrics object + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return descent in milliponts + */ + public int getDescender(String family, int style, int size) { + setFont(family, style, size); + return (-1 * FONT_FACTOR * fmt.getDescent()); + } + + /** + * Determines the typical font height of a small cap letter + * FontMetrics object + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return font height in milliponts + */ + public int getXHeight(String family, int style, int size) { + setFont(family, style, size); + return (int)(FONT_FACTOR * xHeight); + } + + /** + * Returns width (in 1/1000ths of point size) of character at + * code point i + * @param i the character for which to get the width + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return character width in millipoints + */ + public int width(int i, String family, int style, int size) { + int w; + setFont(family, style, size); + // the output seems to look a little better if the + // space is rendered larger than given by + // the FontMetrics object + if (i <= 32) { + w = (int)(1.4 * fmt.charWidth(i) * FONT_FACTOR); + } else { + w = (int)(fmt.charWidth(i) * FONT_FACTOR); + } + return w; + } + + /** + * Return widths (in 1/1000ths of point size) of all + * characters + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return array of character widths in millipoints + */ + public int[] getWidths(String family, int style, int size) { + int i; + + if (width == null) { + width = new int[256]; + } + setFont(family, style, size); + for (i = 0; i < 256; i++) { + width[i] = FONT_FACTOR * fmt.charWidth(i); + } + return width; + } + + /** + * Checks whether the font for which values are + * requested is the one used immediately before or + * whether it is a new one + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return true if the font was changed, false otherwise + */ + private boolean setFont(String family, int style, int size) { + boolean changed = false; + Rectangle2D rect; + TextLayout layout; + int s = (int)(size / 1000f); + + if (f1 == null) { + f1 = new Font(family, style, s); + fmt = graphics.getFontMetrics(f1); + changed = true; + } else { + if ((this.style != style) || !this.family.equals(family) + || this.size != s) { + if (family.equals(this.family)) { + f1 = f1.deriveFont(style, (float)s); + } else { + f1 = new Font(family, style, s); + } + fmt = graphics.getFontMetrics(f1); + changed = true; + } + // else the font is unchanged from last time + } + if (changed) { + layout = new TextLayout("m", f1, graphics.getFontRenderContext()); + rect = layout.getBounds(); + xHeight = (int)rect.getHeight(); + } + // save the family and style for later comparison + this.family = family; + this.style = style; + this.size = s; + return changed; + } + + + /** + * Returns a java.awt.Font instance for the desired + * family, style and size type. + * This is here, so that the font-mapping + * of FOP-defined fonts to java-fonts can be done + * in one place and does not need to occur in + * AWTFontRenderer. + * @param family font family (jave name) to use + * @param style font style (jave def.) to use + * @param size font size + * @return font with the desired characeristics. + */ + public java.awt.Font getFont(String family, int style, int size) { + setFont(family, style, size); + return f1; + /* + * if( setFont(family,style, size) ) fSized = null; + * if( fSized == null || this.size != size ) { + * fSized = f1.deriveFont( size / 1000f ); + * } + * this.size = size; + * return fSized; + */ + } + +} + + + + + + diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java new file mode 100644 index 000000000..1b9ac6e37 --- /dev/null +++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java @@ -0,0 +1,197 @@ +/* + * $Id: AWTRenderer.java,v 1.44 2003/03/07 09:46:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.awt; + +/* + * originally contributed by + * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com + */ + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.print.PageFormat; +import java.awt.print.Pageable; +import java.awt.print.Printable; +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; + +import org.apache.fop.layout.FontInfo; +import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.viewer.Translator; + +/** + * This is FOP's AWT renderer. + */ +public class AWTRenderer extends AbstractRenderer implements Printable, Pageable { + + protected int pageWidth = 0; + protected int pageHeight = 0; + protected double scaleFactor = 100.0; + protected int pageNumber = 0; + protected List pageList = new java.util.Vector(); + //protected ProgressListener progressListener = null; + protected Translator res = null; + + protected Map fontNames = new java.util.Hashtable(); + protected Map fontStyles = new java.util.Hashtable(); + protected Color saveColor = null; + + /** + * Image Object and Graphics Object. The Graphics Object is the Graphics + * object that is contained within the Image Object. + */ + private BufferedImage pageImage = null; + private Graphics2D graphics = null; + + /** + * The current (internal) font name + */ + protected String currentFontName; + + /** + * The current font size in millipoints + */ + protected int currentFontSize; + + /** + * The current colour's red, green and blue component + */ + protected float currentRed = 0; + protected float currentGreen = 0; + protected float currentBlue = 0; + + /** + * The parent component, used to set up the font. + * This is needed as FontSetup needs a live AWT component + * in order to generate valid font measures. + */ + protected Component parent; + + public AWTRenderer(Translator aRes) { + res = aRes; + } + + public void setProducer(String producer) { + } + + public int getPageCount() { + return 0; + } + + public void setupFontInfo(FontInfo fontInfo) { + // create a temp Image to test font metrics on + BufferedImage fontImage = + new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + FontSetup.setup(fontInfo, fontImage.createGraphics()); + } + + /** + * Sets parent component which is used to set up the font. + * This is needed as FontSetup needs a live AWT component + * in order to generate valid font measures. + * @param parent the live AWT component reference + */ + public void setComponent(Component parent) { + this.parent = parent; + } + + public int getPageNumber() { + return pageNumber; + } + + public void setPageNumber(int aValue) { + pageNumber = aValue; + } + + public void setScaleFactor(double newScaleFactor) { + scaleFactor = newScaleFactor; + } + + public double getScaleFactor() { + return scaleFactor; + } + + public BufferedImage getLastRenderedPage() { + return pageImage; + } + + public void startRenderer(OutputStream out) + throws IOException { + } + + public void stopRenderer() + throws IOException { + } + + // Printable Interface + public PageFormat getPageFormat(int pos) { + return null; + } + + public Printable getPrintable(int pos) { + return null; + } + + public int getNumberOfPages() { + return 0; + } + + public int print(Graphics g, PageFormat format, int pos) { + return 0; + } +} diff --git a/src/java/org/apache/fop/render/awt/FontMetricsMapper.java b/src/java/org/apache/fop/render/awt/FontMetricsMapper.java new file mode 100644 index 000000000..cc560a5ef --- /dev/null +++ b/src/java/org/apache/fop/render/awt/FontMetricsMapper.java @@ -0,0 +1,198 @@ +/* + * $Id: FontMetricsMapper.java,v 1.8 2003/03/07 09:46:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.awt; + +// Java +import java.awt.Graphics2D; +import java.util.Map; + +// FOP +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.fonts.FontType; + + +/** + * This class implements org.apache.fop.layout.FontMetrics and + * is added to the hash table in FontInfo. It deferes the + * actual calculation of the metrics to + * AWTFontMetrics. It only keeps the java name and + * style as member varibles + */ + +public class FontMetricsMapper implements FontMetrics { + + /** + * The first and last non space-character + */ + private static final int FIRST_CHAR = 32; + private static final int LAST_CHAR = 255; + + /** + * This is a AWTFontMetrics that does the real calculation. + * It is only one class that dynamically determines the font-size. + */ + private static AWTFontMetrics metric = null; + + /** + * The java name of the font. + * # Make the family name immutable. + */ + private final String family; + + /** + * The java style of the font. + * # Make the style immutable. + */ + private final int style; + + /** + * Constructs a new Font-metrics. + * @param family the family name of the font (java value) + * @param style the java type style value of the font + * @param graphics a Graphics2D object - this is needed so + * that we can get an instance of java.awt.FontMetrics + */ + public FontMetricsMapper(String family, int style, Graphics2D graphics) { + this.family = family; + this.style = style; + if (metric == null) { + metric = new AWTFontMetrics(graphics); + } + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getFontName() + */ + public String getFontName() { + return family; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getFontType() + */ + public FontType getFontType() { + return FontType.OTHER; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getAscender(int) + */ + public int getAscender(int size) { + return metric.getAscender(family, style, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getCapHeight(int) + */ + public int getCapHeight(int size) { + return metric.getCapHeight(family, style, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getDescender(int) + */ + public int getDescender(int size) { + return metric.getDescender(family, style, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getXHeight(int) + */ + public int getXHeight(int size) { + return metric.getXHeight(family, style, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidth(int, int) + */ + public int getWidth(int i, int size) { + return metric.width(i, family, style, size); + } + + + /** + * @see org.apache.fop.fonts.FontMetrics#getWidths() + */ + public int[] getWidths() { + return metric.getWidths(family, style, AWTFontMetrics.FONT_SIZE); + } + + /** + * Gets a Font instance of the Font that this + * FontMetrics describes in the desired size. + * @param size font size + * @return font with the desired characeristics. + */ + public java.awt.Font getFont(int size) { + return metric.getFont(family, style, size); + } + + /** + * @see org.apache.fop.fonts.FontMetrics#getKerningInfo() + */ + public Map getKerningInfo() { + return java.util.Collections.EMPTY_MAP; + } + + /** + * @see org.apache.fop.fonts.FontMetrics#hasKerningInfo() + */ + public boolean hasKerningInfo() { + return false; + } + + +} + + + + + diff --git a/src/java/org/apache/fop/render/awt/FontSetup.java b/src/java/org/apache/fop/render/awt/FontSetup.java new file mode 100644 index 000000000..732e0d721 --- /dev/null +++ b/src/java/org/apache/fop/render/awt/FontSetup.java @@ -0,0 +1,213 @@ +/* + * $Id: FontSetup.java,v 1.7 2003/03/07 09:46:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.awt; + +// FOP +import org.apache.fop.layout.FontInfo; + +// Java +import java.awt.Graphics2D; + +/** + * Sets up the AWT fonts. It is similar to + * org.apache.fop.render.pdf.FontSetup. + * Assigns the font (with metrics) to internal names like "F1" and + * assigns family-style-weight triplets to the fonts. + */ +public class FontSetup { + + + /** + * Sets up the font info object. + * + * Adds metrics for basic fonts and useful family-style-weight + * triplets for lookup. + * + * @param fontInfo the font info object to set up + * @param graphics needed for acces to font metrics + */ + public static void setup(FontInfo fontInfo, Graphics2D graphics) { + FontMetricsMapper metric; + int normal, bold, bolditalic, italic; + + /* + * available java fonts are: + * Serif - bold, normal, italic, bold-italic + * SansSerif - bold, normal, italic, bold-italic + * MonoSpaced - bold, normal, italic, bold-italic + */ + normal = java.awt.Font.PLAIN; + bold = java.awt.Font.BOLD; + italic = java.awt.Font.ITALIC; + bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC; + + metric = new FontMetricsMapper("SansSerif", normal, graphics); + // --> goes to F1 + fontInfo.addMetrics("F1", metric); + metric = new FontMetricsMapper("SansSerif", italic, graphics); + // --> goes to F2 + fontInfo.addMetrics("F2", metric); + metric = new FontMetricsMapper("SansSerif", bold, graphics); + // --> goes to F3 + fontInfo.addMetrics("F3", metric); + metric = new FontMetricsMapper("SansSerif", bolditalic, graphics); + // --> goes to F4 + fontInfo.addMetrics("F4", metric); + + + metric = new FontMetricsMapper("Serif", normal, graphics); + // --> goes to F5 + fontInfo.addMetrics("F5", metric); + metric = new FontMetricsMapper("Serif", italic, graphics); + // --> goes to F6 + fontInfo.addMetrics("F6", metric); + metric = new FontMetricsMapper("Serif", bold, graphics); + // --> goes to F7 + fontInfo.addMetrics("F7", metric); + metric = new FontMetricsMapper("Serif", bolditalic, graphics); + // --> goes to F8 + fontInfo.addMetrics("F8", metric); + + metric = new FontMetricsMapper("MonoSpaced", normal, graphics); + // --> goes to F9 + fontInfo.addMetrics("F9", metric); + metric = new FontMetricsMapper("MonoSpaced", italic, graphics); + // --> goes to F10 + fontInfo.addMetrics("F10", metric); + metric = new FontMetricsMapper("MonoSpaced", bold, graphics); + // --> goes to F11 + fontInfo.addMetrics("F11", metric); + metric = new FontMetricsMapper("MonoSpaced", bolditalic, graphics); + // --> goes to F12 + fontInfo.addMetrics("F12", metric); + + metric = new FontMetricsMapper("Symbol", bolditalic, graphics); + // --> goes to F13 and F14 + fontInfo.addMetrics("F13", metric); + fontInfo.addMetrics("F14", metric); + + // Custom type 1 fonts step 1/2 + // fontInfo.addMetrics("F15", new OMEP()); + // fontInfo.addMetrics("F16", new GaramondLightCondensed()); + // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); + + /* any is treated as serif */ + fontInfo.addFontProperties("F5", "any", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "any", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "any", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "any", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "any", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "any", "oblique", FontInfo.BOLD); + + fontInfo.addFontProperties("F1", "sans-serif", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F3", "sans-serif", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "serif", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "serif", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "serif", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "serif", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "serif", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "serif", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "monospace", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F11", "monospace", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "monospace", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "monospace", "italic", FontInfo.BOLD); + + fontInfo.addFontProperties("F1", "Helvetica", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F3", "Helvetica", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "Times", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "Courier", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F11", "Courier", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "Courier", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "Courier", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F13", "Symbol", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", FontInfo.NORMAL); + + // Custom type 1 fonts step 2/2 + // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); + + /* for compatibility with PassiveTex */ + fontInfo.addFontProperties("F5", "Times-Roman", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times-Roman", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "Times Roman", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times Roman", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter", + "normal", FontInfo.NORMAL); + } + +} + diff --git a/src/java/org/apache/fop/render/package.html b/src/java/org/apache/fop/render/package.html new file mode 100644 index 000000000..25daa021e --- /dev/null +++ b/src/java/org/apache/fop/render/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.render Package + +

generic renderer interface

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java new file mode 100644 index 000000000..fe738e6d8 --- /dev/null +++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java @@ -0,0 +1,217 @@ +/* + * $Id: PCLRenderer.java,v 1.18 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pcl; + +// FOP +import org.apache.fop.render.PrintRenderer; + +// Java +import java.io.IOException; +import java.io.OutputStream; + +/** + * Renderer that renders areas to PCL + * Created by Arthur E Welch III while at M&I EastPoint Technology + * Donated by EastPoint to the Apache FOP project March 2, 2001. + */ +public class PCLRenderer extends PrintRenderer { + + /** + * the current stream to add PCL commands to + */ + protected PCLStream currentStream; + + private int pageHeight = 7920; + + // These variables control the virtual paggination functionality. + private int curdiv = 0; + private int divisions = -1; + private int paperheight = -1; // Paper height in decipoints? + private int orientation = -1; // -1=default/unknown, 0=portrait, 1=landscape. + private int topmargin = -1; // Top margin in decipoints? + private int leftmargin = -1; // Left margin in decipoints? + private int fullmargin = 0; + private final boolean debug = false; + + private int xoffset = -180; // X Offset to allow for PCL implicit 1/4" left margin. + + private java.util.Hashtable options; + + /** + * Create the PCL renderer + */ + public PCLRenderer() { + } + + /** + * set the PCL document's producer + * + * @param producer string indicating application producing PCL + */ + public void setProducer(String producer) { + } + + public void setFont(String name, float size) { + int fontcode = 0; + if (name.length() > 1 && name.charAt(0) == 'F') { + try { + fontcode = Integer.parseInt(name.substring(1)); + } catch (Exception e) { + e.printStackTrace(); + } + } + switch (fontcode) { + case 1: // F1 = Helvetica + // currentStream.add("\033(8U\033(s1p" + (size / 1000) + "v0s0b24580T"); + // Arial is more common among PCL5 printers than Helvetica - so use Arial + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v0s0b16602T"); + break; + case 2: // F2 = Helvetica Oblique + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v1s0b16602T"); + break; + case 3: // F3 = Helvetica Bold + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v0s3b16602T"); + break; + case 4: // F4 = Helvetica Bold Oblique + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v1s3b16602T"); + break; + case 5: // F5 = Times Roman + // currentStream.add("\033(8U\033(s1p" + (size / 1000) + "v0s0b25093T"); + // Times New is more common among PCL5 printers than Times - so use Times New + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v0s0b16901T"); + break; + case 6: // F6 = Times Italic + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v1s0b16901T"); + break; + case 7: // F7 = Times Bold + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v0s3b16901T"); + break; + case 8: // F8 = Times Bold Italic + + currentStream.add("\033(0N\033(s1p" + (size / 1000) + + "v1s3b16901T"); + break; + case 9: // F9 = Courier + + currentStream.add("\033(0N\033(s0p" + + (120.01f / (size / 1000.00f)) + "h0s0b4099T"); + break; + case 10: // F10 = Courier Oblique + + currentStream.add("\033(0N\033(s0p" + + (120.01f / (size / 1000.00f)) + "h1s0b4099T"); + break; + case 11: // F11 = Courier Bold + + currentStream.add("\033(0N\033(s0p" + + (120.01f / (size / 1000.00f)) + "h0s3b4099T"); + break; + case 12: // F12 = Courier Bold Oblique + + currentStream.add("\033(0N\033(s0p" + + (120.01f / (size / 1000.00f)) + "h1s3b4099T"); + break; + case 13: // F13 = Symbol + + currentStream.add("\033(19M\033(s1p" + (size / 1000) + + "v0s0b16686T"); + // ECMA Latin 1 Symbol Set in Times Roman??? + // currentStream.add("\033(9U\033(s1p" + (size / 1000) + "v0s0b25093T"); + break; + case 14: // F14 = Zapf Dingbats + + currentStream.add("\033(14L\033(s1p" + (size / 1000) + + "v0s0b45101T"); + break; + default: + currentStream.add("\033(0N\033(s" + (size / 1000) + "V"); + break; + } + } + + public void startRenderer(OutputStream outputStream) throws IOException { + getLogger().info("rendering areas to PCL"); + currentStream = new PCLStream(outputStream); + + // Set orientation. + if (orientation > -1) { + currentStream.add("\033&l" + orientation + "O"); + } else { + currentStream.add("\033&l0O"); + } + if (orientation == 1 || orientation == 3) { + xoffset = -144; + } else { + xoffset = -180; + } + + // Reset the margins. + currentStream.add("\033" + "9\033&l0E"); + } + + public void stopRenderer() throws IOException { + } + +} diff --git a/src/java/org/apache/fop/render/pcl/PCLStream.java b/src/java/org/apache/fop/render/pcl/PCLStream.java new file mode 100644 index 000000000..ba5a528aa --- /dev/null +++ b/src/java/org/apache/fop/render/pcl/PCLStream.java @@ -0,0 +1,89 @@ +/* + * $Id: PCLStream.java,v 1.5 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pcl; + +import java.io.IOException; +import java.io.OutputStream; + +public class PCLStream { + + private OutputStream out = null; + private boolean doOutput = true; + + public PCLStream(OutputStream os) { + out = os; + } + + public void add(String str) { + if (!doOutput) { + return; + } + + byte buff[] = new byte[str.length()]; + int countr; + int len = str.length(); + for (countr = 0; countr < len; countr++) { + buff[countr] = (byte)str.charAt(countr); + } + try { + out.write(buff); + } catch (IOException e) { + // e.printStackTrace(); + // e.printStackTrace(System.out); + throw new RuntimeException(e.toString()); + } + } + + public void setDoOutput(boolean doout) { + doOutput = doout; + } + +} diff --git a/src/java/org/apache/fop/render/pdf/CTMHelper.java b/src/java/org/apache/fop/render/pdf/CTMHelper.java new file mode 100644 index 000000000..4a3103a01 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/CTMHelper.java @@ -0,0 +1,145 @@ +/* + * $Id: CTMHelper.java,v 1.2 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +import org.apache.fop.area.CTM; + +/** + * CTMHelper converts FOP transformation matrixis to those + * suitable for use by the PDFRender. The e and f elements + * of the matrix will be divided by 1000 as FOP uses millipoints + * as it's default user space and PDF uses points. + * + * @see org.apache.fop.area.CTM + * + * @author 1.0 0.0 0.0 1.0 1.0 1.0
". + * + * @param sourceMatrix - The matrix to convert. + * + * @return a space seperated string containing the matrix elements. + */ + public static String toPDFString(CTM sourceMatrix) { + if (null == sourceMatrix) { + throw new NullPointerException("sourceMatrix must not be null"); + } + + final double matrix[] = toPDFArray(sourceMatrix); + + return matrix[0] + " " + matrix[1] + " " + + matrix[2] + " " + matrix[3] + " " + + matrix[4] + " " + matrix[5]; + } + + /** + *

Creates a new CTM based in the sourceMatrix.

+ *

For example: + *

+     *    org.apache.fop.area.CTM inCTM = 
+     *          new org.apache.fop.area.CTM(1.0, 0.0, 0.0, 1.0, 1000.0, 1000.0);
+     *    org.apache.fop.area.CTM outCTM = 
+     *          org.apache.fop.render.pdf.CTMHelper.toPDFCTM(ctm);
+     * 
+ * will return a new CTM where a == 1.0, b == 0.0, c == 0.0, d == 1.0, e == 1.0 and f == 1.0. + * + * @param sourceMatrix - The matrix to convert. + * + * @return a new converted matrix. + */ + public static CTM toPDFCTM(CTM sourceMatrix) { + if (null == sourceMatrix) { + throw new NullPointerException("sourceMatrix must not be null"); + } + + final double matrix[] = toPDFArray(sourceMatrix); + + return new CTM(matrix[0], matrix[1], matrix[2], matrix[3], + matrix[4], matrix[5]); + } + + /** + *

Creates an array of six doubles from the source CTM.

+ *

For example: + *

+     *    org.apache.fop.area.CTM inCTM = 
+     *          new org.apache.fop.area.CTM(1.0, 0.0, 0.0, 1.0, 1000.0, 1000.0);
+     *    double matrix[] = org.apache.fop.render.pdf.CTMHelper.toPDFArray(ctm);
+     * 
+ * will return a new array where matrix[0] == 1.0, matrix[1] == 0.0, + * matrix[2] == 0.0, matrix[3] == 1.0, + * matrix[4] == 1.0 and matrix[5] == 1.0. + * + * @param sourceMatrix - The matrix to convert. + * @return an array of doubles containing the converted matrix. + */ + public static double[] toPDFArray(CTM sourceMatrix) { + if (null == sourceMatrix) { + throw new NullPointerException("sourceMatrix must not be null"); + } + + final double matrix[] = sourceMatrix.toArray(); + + return new double[]{matrix[0], matrix[1], matrix[2], matrix[3], + matrix[4] / 1000.0, matrix[5] / 1000.0}; + } + +} + diff --git a/src/java/org/apache/fop/render/pdf/EmbedFontInfo.java b/src/java/org/apache/fop/render/pdf/EmbedFontInfo.java new file mode 100644 index 000000000..a78dbd8e0 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/EmbedFontInfo.java @@ -0,0 +1,112 @@ +/* + * $Id: EmbedFontInfo.java,v 1.4 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +import java.util.List; + +/** + * FontInfo contains meta information on fonts (where is the metrics file etc.) + */ +public class EmbedFontInfo { + + private String metricsFile, embedFile; + private boolean kerning; + private List fontTriplets; + + /** + * Main constructor + * @param metricsFile Path to the xml file containing font metrics + * @param kerning True if kerning should be enabled + * @param fontTriplets List of font triplets to associate with this font + * @param embedFile Path to the embeddable font file (may be null) + */ + public EmbedFontInfo(String metricsFile, boolean kerning, + List fontTriplets, String embedFile) { + this.metricsFile = metricsFile; + this.embedFile = embedFile; + this.kerning = kerning; + this.fontTriplets = fontTriplets; + } + + /** + * Returns the path to the metrics file + * @return the metrics file path + */ + public String getMetricsFile() { + return metricsFile; + } + + /** + * Returns the path to the embeddable font file + * @return the font file path + */ + public String getEmbedFile() { + return embedFile; + } + + /** + * Determines if kerning is enabled + * @return True if enabled + */ + public boolean getKerning() { + return kerning; + } + + /** + * Returns the list of font triplets associated with this font. + * @return List of font triplets + */ + public List getFontTriplets() { + return fontTriplets; + } + +} + diff --git a/src/java/org/apache/fop/render/pdf/FontReader.java b/src/java/org/apache/fop/render/pdf/FontReader.java new file mode 100644 index 000000000..375c4e56a --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/FontReader.java @@ -0,0 +1,321 @@ +/* + * $Id: FontReader.java,v 1.8 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +//Java +import java.util.List; +import java.util.Map; +import java.io.IOException; + +//SAX +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; +import org.xml.sax.Locator; +import org.xml.sax.Attributes; +import org.xml.sax.helpers.DefaultHandler; + +//FOP +import org.apache.fop.apps.FOPException; +import org.apache.fop.fonts.BFEntry; +import org.apache.fop.fonts.CIDFontType; +import org.apache.fop.fonts.CustomFont; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontType; +import org.apache.fop.fonts.MultiByteFont; +import org.apache.fop.fonts.SingleByteFont; + +/** + * Class for reading a metric.xml file and creating a font object. + * Typical usage: + *
+ * FontReader reader = new FontReader();
+ * reader.setFontEmbedPath();
+ * reader.useKerning(true);
+ * Font f = reader.getFont();
+ * 
+ */ +public class FontReader extends DefaultHandler { + + private Locator locator = null; + private boolean isCID = false; + private CustomFont returnFont = null; + private MultiByteFont multiFont = null; + private SingleByteFont singleFont = null; + private StringBuffer text = new StringBuffer(); + + private List cidWidths = null; + private int cidWidthIndex = 0; + + private Map currentKerning = null; + + private List bfranges = null; + + private void createFont(String path) throws FOPException { + XMLReader parser = null; + + try { + parser = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + } catch (Exception e) { + throw new FOPException(e); + } + if (parser == null) { + throw new FOPException("Unable to create SAX parser"); + } + + try { + parser.setFeature("http://xml.org/sax/features/namespace-prefixes", + false); + } catch (SAXException e) { + throw new FOPException("You need a SAX parser which supports SAX version 2", + e); + } + + parser.setContentHandler(this); + + try { + parser.parse(path); + } catch (SAXException e) { + throw new FOPException(e); + } catch (IOException e) { + throw new FOPException(e); + } + + } + + /** + * Sets the path to embed a font. A null value disables font embedding. + * @param path URI for the embeddable file + */ + public void setFontEmbedPath(String path) { + returnFont.setEmbedFileName(path); + } + + /** + * Enable/disable use of kerning for the font + * @param enabled true to enable kerning, false to disable + */ + public void setKerningEnabled(boolean enabled) { + returnFont.setKerningEnabled(enabled); + } + + + /** + * Get the generated font object + * @return the font + */ + public Font getFont() { + return returnFont; + } + + /** + * Construct a FontReader object from a path to a metric.xml file + * and read metric data + * @param path URI to the font metric file + * @throws FOPException if loading the font fails + */ + public FontReader(String path) throws FOPException { + createFont(path); + } + + /** + * @see org.xml.sax.ContentHandler#startDocument() + */ + public void startDocument() { + } + + /** + * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator) + */ + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + /** + * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes) + */ + public void startElement(String uri, String localName, String qName, + Attributes attributes) { + if (localName.equals("font-metrics")) { + if ("TYPE0".equals(attributes.getValue("type"))) { + multiFont = new MultiByteFont(); + returnFont = multiFont; + isCID = true; + } else if ("TRUETYPE".equals(attributes.getValue("type"))) { + singleFont = new SingleByteFont(); + singleFont.setFontType(FontType.TRUETYPE); + returnFont = singleFont; + isCID = false; + } else { + singleFont = new SingleByteFont(); + singleFont.setFontType(FontType.TYPE1); + returnFont = singleFont; + isCID = false; + } + } else if ("embed".equals(localName)) { + returnFont.setEmbedFileName(attributes.getValue("file")); + returnFont.setEmbedResourceName(attributes.getValue("class")); + } else if ("cid-widths".equals(localName)) { + cidWidthIndex = getInt(attributes.getValue("start-index")); + cidWidths = new java.util.ArrayList(); + } else if ("kerning".equals(localName)) { + currentKerning = new java.util.HashMap(); + returnFont.putKerningEntry(new Integer(attributes.getValue("kpx1")), + currentKerning); + } else if ("bfranges".equals(localName)) { + bfranges = new java.util.ArrayList(); + } else if ("bf".equals(localName)) { + BFEntry entry = new BFEntry(getInt(attributes.getValue("us")), + getInt(attributes.getValue("ue")), + getInt(attributes.getValue("gi"))); + bfranges.add(entry); + } else if ("wx".equals(localName)) { + cidWidths.add(new Integer(attributes.getValue("w"))); + } else if ("widths".equals(localName)) { + //singleFont.width = new int[256]; + } else if ("char".equals(localName)) { + try { + singleFont.setWidth(Integer.parseInt(attributes.getValue("idx")), + Integer.parseInt(attributes.getValue("wdt"))); + } catch (NumberFormatException ne) { + System.out.println("Malformed width in metric file: " + + ne.getMessage()); + } + } else if ("pair".equals(localName)) { + currentKerning.put(new Integer(attributes.getValue("kpx2")), + new Integer(attributes.getValue("kern"))); + } + } + + private int getInt(String str) { + int ret = 0; + try { + ret = Integer.parseInt(str); + } catch (Exception e) { + /**@todo log this exception */ + } + return ret; + } + + /** + * @see org.xml.sax.ContentHandler#endElement(String, String, String) + */ + public void endElement(String uri, String localName, String qName) { + if ("font-name".equals(localName)) { + returnFont.setFontName(text.toString()); + } else if ("ttc-name".equals(localName) && isCID) { + multiFont.setTTCName(text.toString()); + } else if ("cap-height".equals(localName)) { + returnFont.setCapHeight(getInt(text.toString())); + } else if ("x-height".equals(localName)) { + returnFont.setXHeight(getInt(text.toString())); + } else if ("ascender".equals(localName)) { + returnFont.setAscender(getInt(text.toString())); + } else if ("descender".equals(localName)) { + returnFont.setDescender(getInt(text.toString())); + } else if ("left".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[0] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("bottom".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[1] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("right".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[2] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("top".equals(localName)) { + int[] bbox = returnFont.getFontBBox(); + bbox[3] = getInt(text.toString()); + returnFont.setFontBBox(bbox); + } else if ("first-char".equals(localName)) { + returnFont.setFirstChar(getInt(text.toString())); + } else if ("last-char".equals(localName)) { + returnFont.setLastChar(getInt(text.toString())); + } else if ("flags".equals(localName)) { + returnFont.setFlags(getInt(text.toString())); + } else if ("stemv".equals(localName)) { + returnFont.setStemV(getInt(text.toString())); + } else if ("italic-angle".equals(localName)) { + returnFont.setItalicAngle(getInt(text.toString())); + } else if ("missing-width".equals(localName)) { + returnFont.setMissingWidth(getInt(text.toString())); + } else if ("cid-type".equals(localName)) { + multiFont.setCIDType(CIDFontType.byName(text.toString())); + } else if ("default-width".equals(localName)) { + multiFont.setDefaultWidth(getInt(text.toString())); + } else if ("cid-widths".equals(localName)) { + int[] wds = new int[cidWidths.size()]; + int j = 0; + for (int count = 0; count < cidWidths.size(); count++) { + Integer i = (Integer)cidWidths.get(count); + wds[j++] = i.intValue(); + } + + multiFont.addCIDWidthEntry(cidWidthIndex, wds); + multiFont.setWidthArray(wds); + + } else if ("bfranges".equals(localName)) { + multiFont.setBFEntries((BFEntry[])bfranges.toArray(new BFEntry[0])); + } + text.setLength(0); //Reset text buffer (see characters()) + } + + /** + * @see org.xml.sax.ContentHandler#characters(char[], int, int) + */ + public void characters(char[] ch, int start, int length) { + text.append(ch, start, length); + } + +} + + diff --git a/src/java/org/apache/fop/render/pdf/FontSetup.java b/src/java/org/apache/fop/render/pdf/FontSetup.java new file mode 100644 index 000000000..684fa3652 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/FontSetup.java @@ -0,0 +1,270 @@ +/* + * $Id: FontSetup.java,v 1.22 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +// FOP +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontDescriptor; +import org.apache.fop.fonts.LazyFont; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFResources; +// FOP (base 14 fonts) +import org.apache.fop.fonts.base14.Helvetica; +import org.apache.fop.fonts.base14.HelveticaBold; +import org.apache.fop.fonts.base14.HelveticaOblique; +import org.apache.fop.fonts.base14.HelveticaBoldOblique; +import org.apache.fop.fonts.base14.TimesRoman; +import org.apache.fop.fonts.base14.TimesBold; +import org.apache.fop.fonts.base14.TimesItalic; +import org.apache.fop.fonts.base14.TimesBoldItalic; +import org.apache.fop.fonts.base14.Courier; +import org.apache.fop.fonts.base14.CourierBold; +import org.apache.fop.fonts.base14.CourierOblique; +import org.apache.fop.fonts.base14.CourierBoldOblique; +import org.apache.fop.fonts.base14.Symbol; +import org.apache.fop.fonts.base14.ZapfDingbats; + +// Java +import java.util.Map; +import java.util.Iterator; +import java.util.List; + +/** + * sets up the PDF fonts. + * + * Assigns the font (with metrics) to internal names like "F1" and + * assigns family-style-weight triplets to the fonts + */ +public class FontSetup { + + /** + * Sets up the font info object. + * + * Adds metrics for basic fonts and useful family-style-weight + * triplets for lookup. + * + * @param fontInfo the font info object to set up + * @param embedList ??? + */ + public static void setup(FontInfo fontInfo, List embedList) { + + fontInfo.addMetrics("F1", new Helvetica()); + fontInfo.addMetrics("F2", new HelveticaOblique()); + fontInfo.addMetrics("F3", new HelveticaBold()); + fontInfo.addMetrics("F4", new HelveticaBoldOblique()); + fontInfo.addMetrics("F5", new TimesRoman()); + fontInfo.addMetrics("F6", new TimesItalic()); + fontInfo.addMetrics("F7", new TimesBold()); + fontInfo.addMetrics("F8", new TimesBoldItalic()); + fontInfo.addMetrics("F9", new Courier()); + fontInfo.addMetrics("F10", new CourierOblique()); + fontInfo.addMetrics("F11", new CourierBold()); + fontInfo.addMetrics("F12", new CourierBoldOblique()); + fontInfo.addMetrics("F13", new Symbol()); + fontInfo.addMetrics("F14", new ZapfDingbats()); + + // Custom type 1 fonts step 1/2 + // fontInfo.addMetrics("F15", new OMEP()); + // fontInfo.addMetrics("F16", new GaramondLightCondensed()); + // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic()); + + /* any is treated as serif */ + fontInfo.addFontProperties("F5", "any", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "any", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "any", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "any", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "any", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "any", "oblique", FontInfo.BOLD); + + fontInfo.addFontProperties("F1", "sans-serif", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "sans-serif", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F3", "sans-serif", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "sans-serif", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "serif", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "serif", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "serif", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "serif", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "serif", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "serif", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "monospace", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "monospace", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F11", "monospace", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "monospace", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "monospace", "italic", FontInfo.BOLD); + + fontInfo.addFontProperties("F1", "Helvetica", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F2", "Helvetica", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F3", "Helvetica", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F4", "Helvetica", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "Times", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "Courier", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F10", "Courier", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F11", "Courier", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "Courier", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F12", "Courier", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F13", "Symbol", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", FontInfo.NORMAL); + + // Custom type 1 fonts step 2/2 + // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL); + // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD); + + /* for compatibility with PassiveTex */ + fontInfo.addFontProperties("F5", "Times-Roman", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times-Roman", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times-Roman", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times-Roman", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F5", "Times Roman", "normal", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "oblique", FontInfo.NORMAL); + fontInfo.addFontProperties("F6", "Times Roman", "italic", FontInfo.NORMAL); + fontInfo.addFontProperties("F7", "Times Roman", "normal", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "oblique", FontInfo.BOLD); + fontInfo.addFontProperties("F8", "Times Roman", "italic", FontInfo.BOLD); + fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter", + "normal", FontInfo.NORMAL); + + /* Add configured fonts */ + addConfiguredFonts(fontInfo, embedList, 15); + } + + /** + * Add fonts from configuration file starting with + * internalnames F + * @param fontInfo the font info object to set up + * @param fontInfos ??? + * @param num starting index for internal font numbering + */ + public static void addConfiguredFonts(FontInfo fontInfo, List fontInfos, int num) { + if (fontInfos == null) { + return; //No fonts to process + } + + String internalName = null; + //FontReader reader = null; + + for (int i = 0; i < fontInfos.size(); i++) { + EmbedFontInfo configFontInfo = (EmbedFontInfo)fontInfos.get(i); + + String metricsFile = configFontInfo.getMetricsFile(); + if (metricsFile != null) { + internalName = "F" + num; + num++; + /* + reader = new FontReader(metricsFile); + reader.useKerning(configFontInfo.getKerning()); + reader.setFontEmbedPath(configFontInfo.getEmbedFile()); + fontInfo.addMetrics(internalName, reader.getFont()); + */ + LazyFont font = new LazyFont(configFontInfo.getEmbedFile(), + metricsFile, + configFontInfo.getKerning()); + fontInfo.addMetrics(internalName, font); + + List triplets = configFontInfo.getFontTriplets(); + for (int c = 0; c < triplets.size(); c++) { + FontTriplet triplet = (FontTriplet)triplets.get(c); + + int weight = 400; + try { + weight = Integer.parseInt(triplet.getWeight()); + weight = ((int)weight / 100) * 100; + weight = Math.min(weight, 100); + weight = Math.max(weight, 900); + } catch (NumberFormatException nfe) { + /**@todo log this exception */ + } + fontInfo.addFontProperties(internalName, + triplet.getName(), + triplet.getStyle(), + weight); + } + } + } + } + + /** + * Add the fonts in the font info to the PDF document + * + * @param doc PDF document to add fonts to + * @param resources PDFResources object to attach the font to + * @param fontInfo font info object to get font information from + */ + public static void addToResources(PDFDocument doc, PDFResources resources, FontInfo fontInfo) { + Map fonts = fontInfo.getUsedFonts(); + Iterator e = fonts.keySet().iterator(); + while (e.hasNext()) { + String f = (String)e.next(); + Font font = (Font)fonts.get(f); + FontDescriptor desc = null; + if (font instanceof FontDescriptor) { + desc = (FontDescriptor)font; + } + resources.addFont(doc.makeFont(f, font.getFontName(), + font.getEncoding(), font, desc)); + } + } +} + diff --git a/src/java/org/apache/fop/render/pdf/FontTriplet.java b/src/java/org/apache/fop/render/pdf/FontTriplet.java new file mode 100644 index 000000000..5faeee887 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/FontTriplet.java @@ -0,0 +1,96 @@ +/* + * $Id: FontTriplet.java,v 1.2 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +/** + * FontTriplet contains information on name, weight, style of one font + */ +public class FontTriplet { + + private String name, weight, style; + + /** + * Creates a new font triplet. + * @param name font name + * @param weight font weight (normal, bold etc.) + * @param style font style (normal, italic etc.) + */ + public FontTriplet(String name, String weight, String style) { + this.name = name; + this.weight = weight; + this.style = style; + } + + /** + * Returns the font name. + * @return the font name + */ + public String getName() { + return name; + } + + /** + * Returns the font weight. + * @return the font weight + */ + public String getWeight() { + return weight; + } + + /** + * Returns the font style. + * @return the font style + */ + public String getStyle() { + return style; + } +} + diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java new file mode 100644 index 000000000..4021a26ad --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java @@ -0,0 +1,307 @@ +/* + * $Id: FopPDFImage.java,v 1.7 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +import org.apache.fop.pdf.PDFImage; +import org.apache.fop.pdf.PDFFilter; +import org.apache.fop.pdf.PDFICCStream; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.PDFStream; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.DCTFilter; +import org.apache.fop.pdf.PDFColorSpace; + +import org.apache.fop.image.FopImage; +import org.apache.fop.image.JpegImage; +import org.apache.fop.image.EPSImage; + +import java.io.IOException; +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; +import java.util.Map; + +/** + * PDFImage implementation for the PDF renderer. + */ +public class FopPDFImage implements PDFImage { + + private FopImage fopImage; + private PDFICCStream pdfICCStream = null; + private PDFFilter pdfFilter = null; + private String maskRef; + private String softMaskRef; + private boolean isPS = false; + private Map filters; + private String key; + + /** + * Creates a new PDFImage from a FopImage + * @param image Image + * @param key XObject key + */ + public FopPDFImage(FopImage image, String key) { + fopImage = image; + this.key = key; + isPS = (fopImage instanceof EPSImage); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getKey() + */ + public String getKey() { + // key to look up XObject + return this.key; + } + + /** + * @see org.apache.fop.pdf.PDFImage#setup(PDFDocument) + */ + public void setup(PDFDocument doc) { + filters = doc.getFilterMap(); + if ("image/jpeg".equals(fopImage.getMimeType())) { + pdfFilter = new DCTFilter(); + pdfFilter.setApplied(true); + + JpegImage jpegimage = (JpegImage) fopImage; + ICC_Profile prof = jpegimage.getICCProfile(); + PDFColorSpace pdfCS = toPDFColorSpace(jpegimage.getColorSpace()); + if (prof != null) { + pdfICCStream = doc.makePDFICCStream(); + pdfICCStream.setColorSpace(prof, pdfCS); + pdfICCStream.addDefaultFilters(filters, PDFStream.CONTENT_FILTER); + } + } + } + + /** + * @see org.apache.fop.pdf.PDFImage#isPS() + */ + public boolean isPS() { + return isPS; + } + + /** + * @see org.apache.fop.pdf.PDFImage#getWidth() + */ + public int getWidth() { + return fopImage.getWidth(); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getHeight() + */ + public int getHeight() { + return fopImage.getHeight(); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getColorSpace() + */ + public PDFColorSpace getColorSpace() { + // DeviceGray, DeviceRGB, or DeviceCMYK + return toPDFColorSpace(fopImage.getColorSpace()); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getBitsPerPixel() + */ + public int getBitsPerPixel() { + return fopImage.getBitsPerPixel(); + } + + /** + * @see org.apache.fop.pdf.PDFImage#isTransparent() + */ + public boolean isTransparent() { + return fopImage.isTransparent(); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getTransparentColor() + */ + public PDFColor getTransparentColor() { + return fopImage.getTransparentColor(); + } + + /** + * @see org.apache.fop.pdf.PDFImage#getMask() + */ + public String getMask() { + return maskRef; + } + + /** + * @see org.apache.fop.pdf.PDFImage#getSoftMask() + */ + public String getSoftMask() { + return softMaskRef; + } + + /** + * @see org.apache.fop.pdf.PDFImage#getDataStream() + */ + public PDFStream getDataStream() throws IOException { + if (isPS) { + return getPSDataStream(); + } else { + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + imgStream.setData(fopImage.getBitmaps()); + + /* + * Added by Eric Dalquist + * If the DCT filter hasn't been added to the object we add it here + */ + if (pdfFilter != null) { + imgStream.addFilter(pdfFilter); + } + + imgStream.addDefaultFilters(filters, PDFStream.IMAGE_FILTER); + return imgStream; + } + } + + /** + * Returns a PDFStream for an EPS image. + * @return PDFStream the newly creates PDFStream + * @throws IOException in case of an I/O problem + */ + protected PDFStream getPSDataStream() throws IOException { + int length = 0; + int i = 0; + EPSImage epsImage = (EPSImage) fopImage; + int[] bbox = epsImage.getBBox(); + int bboxw = bbox[2] - bbox[0]; + int bboxh = bbox[3] - bbox[1]; + + // delegate the stream work to PDFStream + PDFStream imgStream = new PDFStream(0); + + StringBuffer preamble = new StringBuffer(); + preamble.append("%%BeginDocument: " + epsImage.getDocName() + "\n"); + + preamble.append("userdict begin % Push userdict on dict stack\n"); + preamble.append("/PreEPS_state save def\n"); + preamble.append("/dict_stack countdictstack def\n"); + preamble.append("/ops_count count 1 sub def\n"); + preamble.append("/showpage {} def\n"); + + + preamble.append((double)(1f / (double) bboxw) + " " + + (double)(1f / (double) bboxh) + " scale\n"); + preamble.append(-bbox[0] + " " + (-bbox[1]) + " translate\n"); + preamble.append(bbox[0] + " " + bbox[1] + " " + + bboxw + " " + bboxh + " rectclip\n"); + preamble.append("newpath\n"); + + StringBuffer post = new StringBuffer(); + post.append("%%EndDocument\n"); + post.append("count ops_count sub {pop} repeat\n"); + post.append("countdictstack dict_stack sub {end} repeat\n"); + post.append("PreEPS_state restore\n"); + post.append("end % userdict\n"); + + byte[] preBytes = preamble.toString().getBytes(); + byte[] postBytes = post.toString().getBytes(); + byte[] epsBytes = ((EPSImage)fopImage).getEPSImage(); + int epsLength = epsBytes.length; + byte[] imgData = new byte[preBytes.length + + postBytes.length + + epsLength]; + + System.arraycopy (preBytes, 0, imgData, 0, preBytes.length); + System.arraycopy (epsBytes, 0, imgData, + preBytes.length, epsBytes.length); + System.arraycopy (postBytes, 0, imgData, + preBytes.length + epsBytes.length, + postBytes.length); + + + imgStream.setData(imgData); + imgStream.addDefaultFilters(filters, PDFStream.CONTENT_FILTER); + + return imgStream; + } + + /** + * @see org.apache.fop.pdf.PDFImage#getICCStream() + */ + public PDFICCStream getICCStream() { + return pdfICCStream; + } + + /** + * Converts a ColorSpace object to a PDFColorSpace object. + * @param cs ColorSpace instance + * @return PDFColorSpace new converted object + */ + public static PDFColorSpace toPDFColorSpace(ColorSpace cs) { + if (cs == null) { + return null; + } + + PDFColorSpace pdfCS = new PDFColorSpace(0); + switch(cs.getType()) { + case ColorSpace.TYPE_CMYK: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_CMYK); + break; + case ColorSpace.TYPE_RGB: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_RGB); + break; + case ColorSpace.TYPE_GRAY: + pdfCS.setColorSpace(PDFColorSpace.DEVICE_GRAY); + break; + } + return pdfCS; + } +} + diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java new file mode 100644 index 000000000..be3734964 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -0,0 +1,1361 @@ +/* + * $Id: PDFRenderer.java,v 1.137 2003/03/05 20:38:27 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +// Java +import java.io.IOException; +import java.io.OutputStream; +import java.awt.Color; +import java.awt.geom.Rectangle2D; +import java.awt.geom.AffineTransform; +import java.util.Map; +import java.util.List; + +// XML +import org.w3c.dom.Document; + +// Avalon +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; + +// FOP +import org.apache.fop.render.PrintRenderer; +import org.apache.fop.render.RendererContext; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.image.FopImage; +import org.apache.fop.image.XMLImage; +import org.apache.fop.image.ImageFactory; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.Version; +import org.apache.fop.fo.properties.RuleStyle; +import org.apache.fop.fo.properties.BackgroundRepeat; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.pdf.PDFStream; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFInfo; +import org.apache.fop.pdf.PDFResources; +import org.apache.fop.pdf.PDFResourceContext; +import org.apache.fop.pdf.PDFXObject; +import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFState; +import org.apache.fop.pdf.PDFLink; +import org.apache.fop.pdf.PDFOutline; +import org.apache.fop.pdf.PDFAnnotList; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.extensions.BookmarkData; + +import org.apache.fop.area.Trait; +import org.apache.fop.area.TreeExt; +import org.apache.fop.area.CTM; +import org.apache.fop.area.Title; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Page; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.Area; +import org.apache.fop.area.Block; +import org.apache.fop.area.BlockViewport; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.inline.Character; +import org.apache.fop.area.inline.Word; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.ForeignObject; +import org.apache.fop.area.inline.Image; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.layout.FontState; +import org.apache.fop.traits.BorderProps; +import org.apache.fop.datatypes.ColorType; + +/* +todo: + +word rendering and optimistion +pdf state optimisation +line and border +background pattern +writing mode +text decoration + + */ + +/** + * Renderer that renders areas to PDF + * + */ +public class PDFRenderer extends PrintRenderer { + /** + * The mime type for pdf + */ + public static final String MIME_TYPE = "application/pdf"; + + /** + * the PDF Document being created + */ + protected PDFDocument pdfDoc; + + /** + * Map of pages using the PageViewport as the key + * this is used for prepared pages that cannot be immediately + * rendered + */ + protected Map pages = null; + + /** + * Page references are stored using the PageViewport as the key + * when a reference is made the PageViewport is used + * for pdf this means we need the pdf page reference + */ + protected Map pageReferences = new java.util.HashMap(); + /** Page viewport references */ + protected Map pvReferences = new java.util.HashMap(); + + private String producer = "FOP"; + + private String creator = null; + + /** + * The output stream to write the document to + */ + protected OutputStream ostream; + + /** + * the /Resources object of the PDF document being created + */ + protected PDFResources pdfResources; + + /** + * the current stream to add PDF commands to + */ + protected PDFStream currentStream; + + /** + * the current annotation list to add annotations to + */ + protected PDFResourceContext currentContext = null; + + /** + * the current page to add annotations to + */ + protected PDFPage currentPage; + + /** drawing state */ + protected PDFState currentState = null; + + /** Name of currently selected font */ + protected String currentFontName = ""; + /** Size of currently selected font */ + protected int currentFontSize = 0; + /** page height */ + protected int pageHeight; + + /** Registry of PDF filters */ + protected Map filterMap = new java.util.HashMap(); + + /** + * true if a TJ command is left to be written + */ + protected boolean textOpen = false; + + /** + * the previous Y coordinate of the last word written. + * Used to decide if we can draw the next word on the same line. + */ + protected int prevWordY = 0; + + /** + * the previous X coordinate of the last word written. + * used to calculate how much space between two words + */ + protected int prevWordX = 0; + + /** + * The width of the previous word. Used to calculate space between + */ + protected int prevWordWidth = 0; + + /** + * reusable word area string buffer to reduce memory usage + */ + private StringBuffer wordAreaPDF = new StringBuffer(); + + /** + * create the PDF renderer + */ + public PDFRenderer() { + } + + /** + * Configure the PDF renderer. + * Get the configuration to be used for pdf stream filters, + * fonts etc. + * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration) + */ + public void configure(Configuration conf) throws ConfigurationException { + Configuration filters = conf.getChild("filterList"); + Configuration[] filt = filters.getChildren("value"); + List filterList = new java.util.ArrayList(); + for (int i = 0; i < filt.length; i++) { + String name = filt[i].getValue(); + filterList.add(name); + } + + filterMap.put(PDFStream.DEFAULT_FILTER, filterList); + + Configuration[] font = conf.getChildren("font"); + for (int i = 0; i < font.length; i++) { + Configuration[] triple = font[i].getChildren("font-triplet"); + List tripleList = new java.util.ArrayList(); + for (int j = 0; j < triple.length; j++) { + tripleList.add(new FontTriplet(triple[j].getAttribute("name"), + triple[j].getAttribute("style"), + triple[j].getAttribute("weight"))); + } + + EmbedFontInfo efi; + efi = new EmbedFontInfo(font[i].getAttribute("metrics-url"), + font[i].getAttributeAsBoolean("kerning"), + tripleList, font[i].getAttribute("embed-url")); + + if (fontList == null) { + fontList = new java.util.ArrayList(); + } + fontList.add(efi); + } + + } + + /** + * Set the document creator. + * + * @param creator string indicating application that is creating the document + */ + public void setCreator(String creator) { + this.creator = creator; + } + + /** + * Set the PDF document's producer. + * + * @param producer string indicating application producing PDF + */ + public void setProducer(String producer) { + this.producer = producer; + } + + /** + * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent) + */ + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + PDFXMLHandler xmlHandler = new PDFXMLHandler(); + //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler); + String svg = "http://www.w3.org/2000/svg"; + userAgent.addXMLHandler(MIME_TYPE, svg, xmlHandler); + } + + /** + * @see org.apache.fop.render.Renderer#startRenderer(OutputStream) + */ + public void startRenderer(OutputStream stream) throws IOException { + ostream = stream; + producer = "FOP " + Version.getVersion(); + this.pdfDoc = new PDFDocument(producer); + this.pdfDoc.setCreator(creator); + this.pdfDoc.setFilterMap(filterMap); + pdfDoc.outputHeader(stream); + } + + /** + * @see org.apache.fop.render.Renderer#stopRenderer() + */ + public void stopRenderer() throws IOException { + FontSetup.addToResources(pdfDoc, pdfDoc.getResources(), fontInfo); + pdfDoc.outputTrailer(ostream); + + this.pdfDoc = null; + ostream = null; + + pages = null; + + pageReferences.clear(); + pvReferences.clear(); + pdfResources = null; + currentStream = null; + currentContext = null; + currentPage = null; + currentState = null; + currentFontName = ""; + wordAreaPDF = new StringBuffer(); + } + + /** + * @see org.apache.fop.render.Renderer#supportsOutOfOrder() + */ + public boolean supportsOutOfOrder() { + return true; + } + + /** + * @see org.apache.fop.render.Renderer#renderExtension(TreeExt) + */ + public void renderExtension(TreeExt ext) { + // render bookmark extension + if (ext instanceof BookmarkData) { + renderRootExtensions((BookmarkData)ext); + } + } + + /** + * Renders the root extension elements + * @param bookmarks the bookmarks to render + */ + protected void renderRootExtensions(BookmarkData bookmarks) { + for (int i = 0; i < bookmarks.getCount(); i++) { + BookmarkData ext = bookmarks.getSubData(i); + renderOutline(ext, null); + } + } + + private void renderOutline(BookmarkData outline, PDFOutline parentOutline) { + PDFOutline outlineRoot = pdfDoc.getOutlineRoot(); + PDFOutline pdfOutline = null; + PageViewport pv = outline.getPage(); + if (pv != null) { + Rectangle2D bounds = pv.getViewArea(); + double h = bounds.getHeight(); + float yoffset = (float)h / 1000f; + String intDest = (String)pageReferences.get(pv.getKey()); + if (parentOutline == null) { + pdfOutline = pdfDoc.makeOutline(outlineRoot, + outline.getLabel(), intDest, yoffset); + } else { + PDFOutline pdfParentOutline = parentOutline; + pdfOutline = pdfDoc.makeOutline(pdfParentOutline, + outline.getLabel(), intDest, yoffset); + } + } + + for (int i = 0; i < outline.getCount(); i++) { + renderOutline(outline.getSubData(i), pdfOutline); + } + } + + /** Saves the graphics state of the rendering engine. */ + protected void saveGraphicsState() { + currentStream.add("q\n"); + } + + /** Restores the last graphics state of the rendering engine. */ + protected void restoreGraphicsState() { + currentStream.add("Q\n"); + } + + /** Indicates the beginning of a text object. */ + protected void beginTextObject() { + currentStream.add("BT\n"); + } + + /** Indicates the end of a text object. */ + protected void endTextObject() { + currentStream.add("ET\n"); + } + + /** + * Start the next page sequence. + * For the pdf renderer there is no concept of page sequences + * but it uses the first available page sequence title to set + * as the title of the pdf document. + * + * @param seqTitle the title of the page sequence + */ + public void startPageSequence(Title seqTitle) { + if (seqTitle != null) { + String str = convertTitleToString(seqTitle); + PDFInfo info = this.pdfDoc.getInfo(); + info.setTitle(str); + } + } + + /** + * The pdf page is prepared by making the page. + * The page is made in the pdf document without any contents + * and then stored to add the contents later. + * The page objects is stored using the area tree PageViewport + * as a key. + * + * @param page the page to prepare + */ + public void preparePage(PageViewport page) { + this.pdfResources = this.pdfDoc.getResources(); + + Rectangle2D bounds = page.getViewArea(); + double w = bounds.getWidth(); + double h = bounds.getHeight(); + currentPage = this.pdfDoc.makePage(this.pdfResources, + (int) Math.round(w / 1000), (int) Math.round(h / 1000)); + if (pages == null) { + pages = new java.util.HashMap(); + } + pages.put(page, currentPage); + pageReferences.put(page.getKey(), currentPage.referencePDF()); + pvReferences.put(page.getKey(), page); + } + + /** + * This method creates a pdf stream for the current page + * uses it as the contents of a new page. The page is written + * immediately to the output stream. + * @see org.apache.fop.render.Renderer#renderPage(PageViewport) + */ + public void renderPage(PageViewport page) + throws IOException, FOPException { + if (pages != null + && (currentPage = (PDFPage) pages.get(page)) != null) { + pages.remove(page); + Rectangle2D bounds = page.getViewArea(); + double h = bounds.getHeight(); + pageHeight = (int) h; + } else { + this.pdfResources = this.pdfDoc.getResources(); + Rectangle2D bounds = page.getViewArea(); + double w = bounds.getWidth(); + double h = bounds.getHeight(); + pageHeight = (int) h; + currentPage = this.pdfDoc.makePage(this.pdfResources, + (int) Math.round(w / 1000), (int) Math.round(h / 1000)); + pageReferences.put(page.getKey(), currentPage.referencePDF()); + pvReferences.put(page.getKey(), page); + } + currentStream = + this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER, false); + + currentState = new PDFState(); + currentState.setTransform(new AffineTransform(1, 0, 0, -1, 0, + (int) Math.round(pageHeight / 1000))); + // Transform origin at top left to origin at bottom left + currentStream.add("1 0 0 -1 0 " + + (int) Math.round(pageHeight / 1000) + " cm\n"); + currentFontName = ""; + + Page p = page.getPage(); + renderPageAreas(p); + + this.pdfDoc.addStream(currentStream); + currentPage.setContents(currentStream); + PDFAnnotList annots = currentPage.getAnnotations(); + if (annots != null) { + this.pdfDoc.addAnnotList(annots); + } + this.pdfDoc.addPage(currentPage); + this.pdfDoc.output(ostream); + } + + + /** + * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) + */ + protected void startVParea(CTM ctm) { + // Set the given CTM in the graphics state + currentState.push(); + currentState.setTransform( + new AffineTransform(CTMHelper.toPDFArray(ctm))); + + saveGraphicsState(); + // multiply with current CTM + currentStream.add(CTMHelper.toPDFString(ctm) + " cm\n"); + // Set clip? + beginTextObject(); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#endVParea() + */ + protected void endVParea() { + endTextObject(); + restoreGraphicsState(); + currentState.pop(); + } + + /** + * Handle the viewport traits. + * This is used to draw the traits for a viewport. + * + * @param region the viewport region to handle + */ + protected void handleViewportTraits(RegionViewport region) { + currentFontName = ""; + float startx = 0; + float starty = 0; + Rectangle2D viewArea = region.getViewArea(); + float width = (float)(viewArea.getWidth() / 1000f); + float height = (float)(viewArea.getHeight() / 1000f); + /* + Trait.Background back; + back = (Trait.Background)region.getTrait(Trait.BACKGROUND); + */ + drawBackAndBorders(region, startx, starty, width, height); + } + + /** + * Handle block traits. + * The block could be any sort of block with any positioning + * so this should render the traits such as border and background + * in its position. + * + * @param block the block to render the traits + */ + protected void handleBlockTraits(Block block) { + float startx = currentIPPosition / 1000f; + float starty = currentBPPosition / 1000f; + drawBackAndBorders(block, startx, starty, + block.getWidth() / 1000f, block.getHeight() / 1000f); + } + + /** + * Draw the background and borders. + * This draws the background and border traits for an area given + * the position. + * + * @param block the area to get the traits from + * @param startx the start x position + * @param starty the start y position + * @param width the width of the area + * @param height the height of the area + */ + protected void drawBackAndBorders(Area block, + float startx, float starty, + float width, float height) { + // draw background then border + + boolean started = false; + Trait.Background back; + back = (Trait.Background)block.getTrait(Trait.BACKGROUND); + if (back != null) { + started = true; + closeText(); + endTextObject(); + //saveGraphicsState(); + + if (back.getColor() != null) { + updateColor(back.getColor(), true, null); + currentStream.add(startx + " " + starty + " " + + width + " " + height + " re\n"); + currentStream.add("f\n"); + } + if (back.getURL() != null) { + ImageFactory fact = ImageFactory.getInstance(); + FopImage fopimage = fact.getImage(back.getURL(), userAgent); + if (fopimage != null && fopimage.load(FopImage.DIMENSIONS, userAgent)) { + if (back.getRepeat() == BackgroundRepeat.REPEAT) { + // create a pattern for the image + } else { + // place once + Rectangle2D pos; + pos = new Rectangle2D.Float((startx + back.getHoriz()) * 1000, + (starty + back.getVertical()) * 1000, + fopimage.getWidth() * 1000, + fopimage.getHeight() * 1000); + putImage(back.getURL(), pos); + } + } + } + } + + BorderProps bps = (BorderProps)block.getTrait(Trait.BORDER_BEFORE); + if (bps != null) { + float endx = startx + width; + + if (!started) { + started = true; + closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width / 1000f; + updateColor(bps.color, false, null); + currentStream.add(bwidth + " w\n"); + + drawLine(startx, starty + bwidth / 2, endx, starty + bwidth / 2); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_START); + if (bps != null) { + float endy = starty + height; + + if (!started) { + started = true; + closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width / 1000f; + updateColor(bps.color, false, null); + currentStream.add(bwidth + " w\n"); + + drawLine(startx + bwidth / 2, starty, startx + bwidth / 2, endy); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_AFTER); + if (bps != null) { + float sy = starty + height; + float endx = startx + width; + + if (!started) { + started = true; + closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width / 1000f; + updateColor(bps.color, false, null); + currentStream.add(bwidth + " w\n"); + + drawLine(startx, sy - bwidth / 2, endx, sy - bwidth / 2); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_END); + if (bps != null) { + float sx = startx + width; + float endy = starty + height; + + if (!started) { + started = true; + closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width / 1000f; + updateColor(bps.color, false, null); + currentStream.add(bwidth + " w\n"); + drawLine(sx - bwidth / 2, starty, sx - bwidth / 2, endy); + } + if (started) { + //restoreGraphicsState(); + beginTextObject(); + // font last set out of scope in text section + currentFontName = ""; + } + } + + /** + * Draw a line. + * + * @param startx the start x position + * @param starty the start y position + * @param endx the x end position + * @param endy the y end position + */ + private void drawLine(float startx, float starty, float endx, float endy) { + currentStream.add(startx + " " + starty + " m\n"); + currentStream.add(endx + " " + endy + " l\n"); + currentStream.add("S\n"); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List) + */ + protected void renderBlockViewport(BlockViewport bv, List children) { + // clip and position viewport if necessary + + // save positions + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + String saveFontName = currentFontName; + + CTM ctm = bv.getCTM(); + + if (bv.getPositioning() == Block.ABSOLUTE) { + + currentIPPosition = 0; + currentBPPosition = 0; + + closeText(); + endTextObject(); + + if (bv.getClip()) { + saveGraphicsState(); + float x = (float)(bv.getXOffset() + containingIPPosition) / 1000f; + float y = (float)(bv.getYOffset() + containingBPPosition) / 1000f; + float width = (float)bv.getWidth() / 1000f; + float height = (float)bv.getHeight() / 1000f; + clip(x, y, width, height); + } + + CTM tempctm = new CTM(containingIPPosition, containingBPPosition); + ctm = tempctm.multiply(ctm); + + startVParea(ctm); + handleBlockTraits(bv); + renderBlocks(children); + endVParea(); + + if (bv.getClip()) { + restoreGraphicsState(); + } + beginTextObject(); + + // clip if necessary + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } else { + + if (ctm != null) { + currentIPPosition = 0; + currentBPPosition = 0; + + closeText(); + endTextObject(); + + double[] vals = ctm.toArray(); + //boolean aclock = vals[2] == 1.0; + if (vals[2] == 1.0) { + ctm = ctm.translate(-saveBP - bv.getHeight(), -saveIP); + } else if (vals[0] == -1.0) { + ctm = ctm.translate(-saveIP - bv.getWidth(), -saveBP - bv.getHeight()); + } else { + ctm = ctm.translate(saveBP, saveIP - bv.getWidth()); + } + } + + // clip if necessary + if (bv.getClip()) { + if (ctm == null) { + closeText(); + endTextObject(); + } + saveGraphicsState(); + float x = (float)bv.getXOffset() / 1000f; + float y = (float)bv.getYOffset() / 1000f; + float width = (float)bv.getWidth() / 1000f; + float height = (float)bv.getHeight() / 1000f; + clip(x, y, width, height); + } + + if (ctm != null) { + startVParea(ctm); + } + handleBlockTraits(bv); + renderBlocks(children); + if (ctm != null) { + endVParea(); + } + + if (bv.getClip()) { + restoreGraphicsState(); + if (ctm == null) { + beginTextObject(); + } + } + if (ctm != null) { + beginTextObject(); + } + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + currentBPPosition += (int)(bv.getHeight()); + } + currentFontName = saveFontName; + } + + /** + * Clip an area. + * write a clipping operation given coordinates in the current + * transform. + * @param x the x coordinate + * @param y the y coordinate + * @param width the width of the area + * @param height the height of the area + */ + protected void clip(float x, float y, float width, float height) { + currentStream.add(x + " " + y + " m\n"); + currentStream.add((x + width) + " " + y + " l\n"); + currentStream.add((x + width) + " " + (y + height) + " l\n"); + currentStream.add(x + " " + (y + height) + " l\n"); + currentStream.add("h\n"); + currentStream.add("W\n"); + currentStream.add("n\n"); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderLineArea(LineArea) + */ + protected void renderLineArea(LineArea line) { + super.renderLineArea(line); + closeText(); + } + + /** + * Render inline parent area. + * For pdf this handles the inline parent area traits such as + * links, border, background. + * @param ip the inline parent area + */ + public void renderInlineParent(InlineParent ip) { + float start = currentBlockIPPosition / 1000f; + float top = (ip.getOffset() + currentBPPosition) / 1000f; + float width = ip.getWidth() / 1000f; + float height = ip.getHeight() / 1000f; + drawBackAndBorders(ip, start, top, width, height); + + // render contents + super.renderInlineParent(ip); + + // place the link over the top + Object tr = ip.getTrait(Trait.INTERNAL_LINK); + boolean internal = false; + String dest = null; + float yoffset = 0; + if (tr == null) { + dest = (String)ip.getTrait(Trait.EXTERNAL_LINK); + } else { + String pvKey = (String)tr; + dest = (String)pageReferences.get(pvKey); + if (dest != null) { + PageViewport pv = (PageViewport)pvReferences.get(pvKey); + Rectangle2D bounds = pv.getViewArea(); + double h = bounds.getHeight(); + yoffset = (float)h / 1000f; + internal = true; + } + } + if (dest != null) { + // add link to pdf document + Rectangle2D rect = new Rectangle2D.Float(start, top, width, height); + // transform rect to absolute coords + AffineTransform transform = currentState.getTransform(); + rect = transform.createTransformedShape(rect).getBounds(); + + int type = internal ? PDFLink.INTERNAL : PDFLink.EXTERNAL; + PDFLink pdflink = pdfDoc.makeLink(rect, dest, type, yoffset); + currentPage.addAnnotation(pdflink); + } + } + + /** + * @see org.apache.fop.render.Renderer#renderCharacter(Character) + */ + public void renderCharacter(Character ch) { + + super.renderCharacter(ch); + } + + /** + * @see org.apache.fop.render.Renderer#renderWord(Word) + */ + public void renderWord(Word word) { + StringBuffer pdf = new StringBuffer(); + + String name = (String) word.getTrait(Trait.FONT_NAME); + int size = ((Integer) word.getTrait(Trait.FONT_SIZE)).intValue(); + + // This assumes that *all* CIDFonts use a /ToUnicode mapping + Font f = (Font) fontInfo.getFonts().get(name); + boolean useMultiByte = f.isMultiByte(); + + // String startText = useMultiByte ? " " : ") "; + + updateFont(name, size, pdf); + ColorType ct = (ColorType)word.getTrait(Trait.COLOR); + if (ct != null) { + updateColor(ct, true, pdf); + } + + int rx = currentBlockIPPosition; + // int bl = pageHeight - currentBPPosition; + int bl = currentBPPosition + word.getOffset(); + + // Set letterSpacing + //float ls = fs.getLetterSpacing() / this.currentFontSize; + //pdf.append(ls).append(" Tc\n"); + + if (!textOpen || bl != prevWordY) { + closeText(); + + pdf.append("1 0 0 -1 " + (rx / 1000f) + " " + + (bl / 1000f) + " Tm [" + startText); + prevWordY = bl; + textOpen = true; + } else { + // express the space between words in thousandths of an em + int space = prevWordX - rx + prevWordWidth; + float emDiff = (float) space / (float) currentFontSize * 1000f; + // this prevents a problem in Acrobat Reader and other viewers + // where large numbers cause text to disappear or default to + // a limit + if (emDiff < -33000) { + closeText(); + + pdf.append("1 0 0 1 " + (rx / 1000f) + " " + + (bl / 1000f) + " Tm [" + startText); + textOpen = true; + } else { + pdf.append(Float.toString(emDiff)); + pdf.append(" "); + pdf.append(startText); + } + } + prevWordWidth = word.getWidth(); + prevWordX = rx; + + String s = word.getWord(); + + FontMetrics metrics = fontInfo.getMetricsFor(name); + FontState fs = new FontState(name, metrics, size); + escapeText(s, fs, useMultiByte, pdf); + pdf.append(endText); + + currentStream.add(pdf.toString()); + + super.renderWord(word); + } + + /** + * Escapes text according to PDF rules. + * @param s Text to escape + * @param fs Font state + * @param useMultiByte Indicates the use of multi byte convention + * @param pdf target buffer for the escaped text + */ + public void escapeText(String s, FontState fs, + boolean useMultiByte, StringBuffer pdf) { + String startText = useMultiByte ? "<" : "("; + String endText = useMultiByte ? "> " : ") "; + + boolean kerningAvailable = false; + Map kerning = fs.getKerning(); + if (kerning != null && !kerning.isEmpty()) { + kerningAvailable = true; + } + + int l = s.length(); + + for (int i = 0; i < l; i++) { + char ch = fs.mapChar(s.charAt(i)); + + if (!useMultiByte) { + if (ch > 127) { + pdf.append("\\"); + pdf.append(Integer.toOctalString((int) ch)); + } else { + switch (ch) { + case '(': + case ')': + case '\\': + pdf.append("\\"); + break; + } + pdf.append(ch); + } + } else { + pdf.append(getUnicodeString(ch)); + } + + if (kerningAvailable && (i + 1) < l) { + addKerning(pdf, (new Integer((int) ch)), + (new Integer((int) fs.mapChar(s.charAt(i + 1))) + ), kerning, startText, endText); + } + } + } + + /** + * Convert a char to a multibyte hex representation + */ + private String getUnicodeString(char c) { + StringBuffer buf = new StringBuffer(4); + + byte[] uniBytes = null; + try { + char[] a = {c}; + uniBytes = new String(a).getBytes("UnicodeBigUnmarked"); + } catch (java.io.UnsupportedEncodingException e) { + // This should never fail + } + + for (int i = 0; i < uniBytes.length; i++) { + int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) + : (int) uniBytes[i]; + + String hexString = Integer.toHexString(b); + if (hexString.length() == 1) { + buf = buf.append("0" + hexString); + } else { + buf = buf.append(hexString); + } + } + return buf.toString(); + } + + private void addKerning(StringBuffer buf, Integer ch1, Integer ch2, + Map kerning, String startText, String endText) { + Map kernPair = (Map) kerning.get(ch1); + + if (kernPair != null) { + Integer width = (Integer) kernPair.get(ch2); + if (width != null) { + buf.append(endText).append(-width.intValue()); + buf.append(' ').append(startText); + } + } + } + + /** + * Checks to see if we have some text rendering commands open + * still and writes out the TJ command to the stream if we do + */ + protected void closeText() { + if (textOpen) { + currentStream.add("] TJ\n"); + textOpen = false; + prevWordX = 0; + prevWordY = 0; + } + } + + private void updateColor(ColorType col, boolean fill, StringBuffer pdf) { + Color newCol = new Color(col.getRed(), col.getGreen(), col.getBlue()); + boolean update = false; + if (fill) { + update = currentState.setBackColor(newCol); + } else { + update = currentState.setColor(newCol); + } + + if (update) { + PDFColor color = new PDFColor((double)col.getRed(), + (double)col.getGreen(), + (double)col.getBlue()); + + closeText(); + + if (pdf != null) { + pdf.append(color.getColorSpaceOut(fill)); + } else { + currentStream.add(color.getColorSpaceOut(fill)); + } + } + } + + private void updateFont(String name, int size, StringBuffer pdf) { + if ((!name.equals(this.currentFontName)) + || (size != this.currentFontSize)) { + closeText(); + + this.currentFontName = name; + this.currentFontSize = size; + pdf = pdf.append("/" + name + " " + ((float) size / 1000f) + + " Tf\n"); + } + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderImage(Image, Rectangle2D) + */ + public void renderImage(Image image, Rectangle2D pos) { + String url = image.getURL(); + putImage(url, pos); + } + + /** + * Adds a PDF XObject (a bitmap) to the PDF that will later be referenced. + * @param url URL of the bitmap + * @param pos Position of the bitmap + */ + protected void putImage(String url, Rectangle2D pos) { + PDFXObject xobject = pdfDoc.getImage(url); + if (xobject != null) { + int w = (int) pos.getWidth() / 1000; + int h = (int) pos.getHeight() / 1000; + placeImage((int) pos.getX() / 1000, + (int) pos.getY() / 1000, w, h, xobject.getXNumber()); + return; + } + + ImageFactory fact = ImageFactory.getInstance(); + FopImage fopimage = fact.getImage(url, userAgent); + if (fopimage == null) { + return; + } + if (!fopimage.load(FopImage.DIMENSIONS, userAgent)) { + return; + } + String mime = fopimage.getMimeType(); + if ("text/xml".equals(mime)) { + if (!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { + return; + } + Document doc = ((XMLImage) fopimage).getDocument(); + String ns = ((XMLImage) fopimage).getNameSpace(); + + renderDocument(doc, ns, pos); + } else if ("image/svg+xml".equals(mime)) { + if (!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { + return; + } + Document doc = ((XMLImage) fopimage).getDocument(); + String ns = ((XMLImage) fopimage).getNameSpace(); + + renderDocument(doc, ns, pos); + } else if ("image/eps".equals(mime)) { + if (!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { + return; + } + FopPDFImage pdfimage = new FopPDFImage(fopimage, url); + int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); + fact.releaseImage(url, userAgent); + } else if ("image/jpeg".equals(mime)) { + if (!fopimage.load(FopImage.ORIGINAL_DATA, userAgent)) { + return; + } + FopPDFImage pdfimage = new FopPDFImage(fopimage, url); + int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); + fact.releaseImage(url, userAgent); + + int w = (int) pos.getWidth() / 1000; + int h = (int) pos.getHeight() / 1000; + placeImage((int) pos.getX() / 1000, + (int) pos.getY() / 1000, w, h, xobj); + } else { + if (!fopimage.load(FopImage.BITMAP, userAgent)) { + return; + } + FopPDFImage pdfimage = new FopPDFImage(fopimage, url); + int xobj = pdfDoc.addImage(currentContext, pdfimage).getXNumber(); + fact.releaseImage(url, userAgent); + + int w = (int) pos.getWidth() / 1000; + int h = (int) pos.getHeight() / 1000; + placeImage((int) pos.getX() / 1000, + (int) pos.getY() / 1000, w, h, xobj); + } + + // output new data + try { + this.pdfDoc.output(ostream); + } catch (IOException ioe) { + // ioexception will be caught later + } + } + + /** + * Places a previously registered image at a certain place on the page. + * @param x X coordinate + * @param y Y coordinate + * @param w width for image + * @param h height for image + * @param xobj object number of the referenced image + */ + protected void placeImage(int x, int y, int w, int h, int xobj) { + saveGraphicsState(); + currentStream.add(((float) w) + " 0 0 " + + ((float) -h) + " " + + (((float) currentBlockIPPosition) / 1000f + x) + " " + + (((float)(currentBPPosition + 1000 * h)) / 1000f + + y) + " cm\n" + "/Im" + xobj + " Do\n"); + restoreGraphicsState(); + + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + renderDocument(doc, ns, pos); + } + + /** + * Renders an XML document (SVG for example). + * @param doc DOM document representing the XML document + * @param ns Namespace for the document + * @param pos Position on the page + */ + public void renderDocument(Document doc, String ns, Rectangle2D pos) { + RendererContext context; + context = new RendererContext(MIME_TYPE); + context.setUserAgent(userAgent); + + context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); + context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream); + context.setProperty(PDFXMLHandler.PDF_STATE, currentState); + context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage); + context.setProperty(PDFXMLHandler.PDF_CONTEXT, + currentContext == null ? currentPage : currentContext); + context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext); + context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream); + context.setProperty(PDFXMLHandler.PDF_XPOS, + new Integer(currentBlockIPPosition + (int) pos.getX())); + context.setProperty(PDFXMLHandler.PDF_YPOS, + new Integer(currentBPPosition + (int) pos.getY())); + context.setProperty(PDFXMLHandler.PDF_FONT_INFO, fontInfo); + context.setProperty(PDFXMLHandler.PDF_FONT_NAME, currentFontName); + context.setProperty(PDFXMLHandler.PDF_FONT_SIZE, + new Integer(currentFontSize)); + context.setProperty(PDFXMLHandler.PDF_WIDTH, + new Integer((int) pos.getWidth())); + context.setProperty(PDFXMLHandler.PDF_HEIGHT, + new Integer((int) pos.getHeight())); + userAgent.renderXML(context, doc, ns); + + } + + /** + * Render an inline viewport. + * This renders an inline viewport by clipping if necessary. + * @param viewport the viewport to handle + */ + public void renderViewport(Viewport viewport) { + closeText(); + + float x = currentBlockIPPosition / 1000f; + float y = (currentBPPosition + viewport.getOffset()) / 1000f; + float width = viewport.getWidth() / 1000f; + float height = viewport.getHeight() / 1000f; + drawBackAndBorders(viewport, x, y, width, height); + + endTextObject(); + + if (viewport.getClip()) { + saveGraphicsState();; + + clip(x, y, width, height); + } + super.renderViewport(viewport); + + if (viewport.getClip()) { + restoreGraphicsState(); + } + beginTextObject(); + } + + /** + * Render leader area. + * This renders a leader area which is an area with a rule. + * @param area the leader area to render + */ + public void renderLeader(Leader area) { + closeText(); + endTextObject(); + saveGraphicsState(); + int style = area.getRuleStyle(); + boolean alt = false; + switch(style) { + case RuleStyle.SOLID: + currentStream.add("[] 0 d\n"); + break; + case RuleStyle.DOTTED: + currentStream.add("[2] 0 d\n"); + break; + case RuleStyle.DASHED: + currentStream.add("[6 4] 0 d\n"); + break; + case RuleStyle.DOUBLE: + case RuleStyle.GROOVE: + case RuleStyle.RIDGE: + alt = true; + break; + } + float startx = ((float) currentBlockIPPosition) / 1000f; + float starty = ((currentBPPosition + area.getOffset()) / 1000f); + float endx = (currentBlockIPPosition + area.getWidth()) / 1000f; + if (!alt) { + currentStream.add(area.getRuleThickness() / 1000f + " w\n"); + drawLine(startx, starty, endx, starty); + } else { + if (style == RuleStyle.DOUBLE) { + float third = area.getRuleThickness() / 3000f; + currentStream.add(third + " w\n"); + drawLine(startx, starty, endx, starty); + + drawLine(startx, (starty + 2 * third), endx, (starty + 2 * third)); + } else { + float half = area.getRuleThickness() / 2000f; + + currentStream.add("1 g\n"); + currentStream.add(startx + " " + starty + " m\n"); + currentStream.add(endx + " " + starty + " l\n"); + currentStream.add(endx + " " + (starty + 2 * half) + " l\n"); + currentStream.add(startx + " " + (starty + 2 * half) + " l\n"); + currentStream.add("h\n"); + currentStream.add("f\n"); + if (style == RuleStyle.GROOVE) { + currentStream.add("0 g\n"); + currentStream.add(startx + " " + starty + " m\n"); + currentStream.add(endx + " " + starty + " l\n"); + currentStream.add(endx + " " + (starty + half) + " l\n"); + currentStream.add((startx + half) + " " + (starty + half) + " l\n"); + currentStream.add(startx + " " + (starty + 2 * half) + " l\n"); + } else { + currentStream.add("0 g\n"); + currentStream.add(endx + " " + starty + " m\n"); + currentStream.add(endx + " " + (starty + 2 * half) + " l\n"); + currentStream.add(startx + " " + (starty + 2 * half) + " l\n"); + currentStream.add(startx + " " + (starty + half) + " l\n"); + currentStream.add((endx - half) + " " + (starty + half) + " l\n"); + } + currentStream.add("h\n"); + currentStream.add("f\n"); + } + + } + + restoreGraphicsState(); + beginTextObject(); + super.renderLeader(area); + } +} + diff --git a/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java b/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java new file mode 100644 index 000000000..f58d71da6 --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/PDFXMLHandler.java @@ -0,0 +1,338 @@ +/* + * $Id: PDFXMLHandler.java,v 1.13 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.pdf; + +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFState; +import org.apache.fop.pdf.PDFStream; +import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFResourceContext; +import org.apache.fop.svg.PDFTextElementBridge; +import org.apache.fop.svg.PDFAElementBridge; +import org.apache.fop.svg.PDFGraphics2D; +import org.apache.fop.svg.SVGUserAgent; +import org.apache.fop.layout.FontInfo; + +import org.w3c.dom.Document; + +import java.io.OutputStream; + +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.ViewBox; + +import org.apache.batik.gvt.GraphicsNode; + +import org.w3c.dom.svg.SVGDocument; +import org.w3c.dom.svg.SVGSVGElement; + +import java.awt.geom.AffineTransform; + +/** + * PDF XML handler. + * This handler handles XML for foreign objects when rendering to PDF. + * It renders SVG to the PDF document using the PDFGraphics2D. + * The properties from the PDF renderer are subject to change. + */ +public class PDFXMLHandler implements XMLHandler { + /** + * The PDF document that is being drawn into. + */ + public static final String PDF_DOCUMENT = "pdfDoc"; + + /** + * The output stream that the document is being sent to. + */ + public static final String OUTPUT_STREAM = "outputStream"; + + /** + * The current pdf state. + */ + public static final String PDF_STATE = "pdfState"; + + /** + * The current PDF page for page renference and as a resource context. + */ + public static final String PDF_PAGE = "pdfPage"; + + /** + * The current PDF page for page renference and as a resource context. + */ + public static final String PDF_CONTEXT = "pdfContext"; + + /** + * The current PDF stream to draw directly to. + */ + public static final String PDF_STREAM = "pdfStream"; + + /** + * The width of the current pdf page. + */ + public static final String PDF_WIDTH = "width"; + + /** + * The height of the current pdf page. + */ + public static final String PDF_HEIGHT = "height"; + + /** + * The current font information for the pdf renderer. + */ + public static final String PDF_FONT_INFO = "fontInfo"; + + /** + * The current pdf font name. + */ + public static final String PDF_FONT_NAME = "fontName"; + + /** + * The current pdf font size. + */ + public static final String PDF_FONT_SIZE = "fontSize"; + + /** + * The x position that this is being drawn at. + */ + public static final String PDF_XPOS = "xpos"; + + /** + * The y position that this is being drawn at. + */ + public static final String PDF_YPOS = "ypos"; + + /** + * Create a new PDF XML handler for use by the PDF renderer. + */ + public PDFXMLHandler() { + } + + /** + * Handle the XML. + * This checks the type of XML and handles appropraitely. + * + * @param context the renderer context + * @param doc the XML document to render + * @param ns the namespace of the XML document + * @throws Exception any sort of exception could be thrown and shuld be handled + */ + public void handleXML(RendererContext context, Document doc, + String ns) throws Exception { + PDFInfo pdfi = getPDFInfo(context); + + String svg = "http://www.w3.org/2000/svg"; + if (svg.equals(ns)) { + SVGHandler svghandler = new SVGHandler(); + svghandler.renderSVGDocument(context, doc, pdfi); + } else { + } + } + + /** + * Get the pdf information from the render context. + * + * @param context the renderer context + * @return the pdf information retrieved from the context + */ + public static PDFInfo getPDFInfo(RendererContext context) { + PDFInfo pdfi = new PDFInfo(); + pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT); + pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM); + pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE); + pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE); + pdfi.pdfContext = (PDFResourceContext)context.getProperty(PDF_CONTEXT); + pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM); + pdfi.width = ((Integer)context.getProperty(PDF_WIDTH)).intValue(); + pdfi.height = ((Integer)context.getProperty(PDF_HEIGHT)).intValue(); + pdfi.fi = (FontInfo)context.getProperty(PDF_FONT_INFO); + pdfi.currentFontName = (String)context.getProperty(PDF_FONT_NAME); + pdfi.currentFontSize = ((Integer)context.getProperty(PDF_FONT_SIZE)).intValue(); + pdfi.currentXPosition = ((Integer)context.getProperty(PDF_XPOS)).intValue(); + pdfi.currentYPosition = ((Integer)context.getProperty(PDF_YPOS)).intValue(); + return pdfi; + } + + /** + * PDF information structure for drawing the XML document. + */ + public static class PDFInfo { + /** see PDF_DOCUMENT */ + public PDFDocument pdfDoc; + /** see OUTPUT_STREAM */ + public OutputStream outputStream; + /** see PDF_STATE */ + public PDFState pdfState; + /** see PDF_PAGE */ + public PDFPage pdfPage; + /** see PDF_CONTEXT */ + public PDFResourceContext pdfContext; + /** see PDF_STREAM */ + public PDFStream currentStream; + /** see PDF_WIDTH */ + public int width; + /** see PDF_HEIGHT */ + public int height; + /** see PDF_FONT_INFO */ + public FontInfo fi; + /** see PDF_FONT_NAME */ + public String currentFontName; + /** see PDF_FONT_SIZE */ + public int currentFontSize; + /** see PDF_XPOS */ + public int currentXPosition; + /** see PDF_YPOS */ + public int currentYPosition; + } + + /** + * This method is placed in an inner class so that we don't get class + * loading errors if batik is not present. + */ + protected class SVGHandler { + /** + * Render the svg document. + * @param context the renderer context + * @param doc the svg document + * @param pdfInfo the pdf information of the current context + */ + protected void renderSVGDocument(RendererContext context, Document doc, PDFInfo pdfInfo) { + int xOffset = pdfInfo.currentXPosition; + int yOffset = pdfInfo.currentYPosition; + + SVGUserAgent ua + = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + + GVTBuilder builder = new GVTBuilder(); + BridgeContext ctx = new BridgeContext(ua); + PDFTextElementBridge tBridge = new PDFTextElementBridge(pdfInfo.fi); + ctx.putBridge(tBridge); + + PDFAElementBridge aBridge = new PDFAElementBridge(); + // to get the correct transform we need to use the PDFState + AffineTransform transform = pdfInfo.pdfState.getTransform(); + transform.translate(xOffset / 1000f, yOffset / 1000f); + aBridge.setCurrentTransform(transform); + ctx.putBridge(aBridge); + + GraphicsNode root; + try { + root = builder.build(ctx, doc); + } catch (Exception e) { + context.getUserAgent().getLogger().error("svg graphic could not be built: " + + e.getMessage(), e); + return; + } + // get the 'width' and 'height' attributes of the SVG document + float w = (float)ctx.getDocumentSize().getWidth() * 1000f; + float h = (float)ctx.getDocumentSize().getHeight() * 1000f; + + float sx = pdfInfo.width / (float)w; + float sy = pdfInfo.height / (float)h; + + ctx = null; + builder = null; + + /* + * Clip to the svg area. + * Note: To have the svg overlay (under) a text area then use + * an fo:block-container + */ + pdfInfo.currentStream.add("q\n"); + // transform so that the coordinates (0,0) is from the top left + // and positive is down and to the right. (0,0) is where the + // viewBox puts it. + pdfInfo.currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f + " " + + yOffset / 1000f + " cm\n"); + + SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); + AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, w / 1000f, h / 1000f); + if (!at.isIdentity()) { + double[] vals = new double[6]; + at.getMatrix(vals); + pdfInfo.currentStream.add(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " " + + PDFNumber.doubleOut(vals[2], 5) + " " + + PDFNumber.doubleOut(vals[3], 5) + " " + + PDFNumber.doubleOut(vals[4]) + " " + + PDFNumber.doubleOut(vals[5]) + " cm\n"); + } + + if (pdfInfo.pdfContext == null) { + pdfInfo.pdfContext = pdfInfo.pdfPage; + } + PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fi, pdfInfo.pdfDoc, + pdfInfo.pdfContext, pdfInfo.pdfPage.referencePDF(), + pdfInfo.currentFontName, + pdfInfo.currentFontSize); + graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); + pdfInfo.pdfState.push(); + transform = new AffineTransform(); + // scale to viewbox + transform.translate(xOffset / 1000f, yOffset / 1000f); + pdfInfo.pdfState.setTransform(transform); + graphics.setPDFState(pdfInfo.pdfState); + graphics.setOutputStream(pdfInfo.outputStream); + try { + root.paint(graphics); + pdfInfo.currentStream.add(graphics.getString()); + } catch (Exception e) { + context.getUserAgent().getLogger().error("svg graphic could not be rendered: " + + e.getMessage(), e); + } + + pdfInfo.currentStream.add("Q\n"); + pdfInfo.pdfState.pop(); + } + } +} + diff --git a/src/java/org/apache/fop/render/pdf/package.html b/src/java/org/apache/fop/render/pdf/package.html new file mode 100644 index 000000000..1bcf2644f --- /dev/null +++ b/src/java/org/apache/fop/render/pdf/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.render.pdf Package + +

classes for rendering to PDF

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/render/ps/ASCII85OutputStream.java b/src/java/org/apache/fop/render/ps/ASCII85OutputStream.java new file mode 100644 index 000000000..7a0c2aeef --- /dev/null +++ b/src/java/org/apache/fop/render/ps/ASCII85OutputStream.java @@ -0,0 +1,254 @@ +/* + * $Id: ASCII85OutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.OutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; + +/** + * This class applies a ASCII85 encoding to the stream. + * + * @author
Jeremias Maerki + * @version $Id: ASCII85OutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + */ +public class ASCII85OutputStream extends FilterOutputStream + implements Finalizable { + + private static final int ZERO = 0x7A; //"z" + private static final byte[] ZERO_ARRAY = {(byte)ZERO}; + private static final int START = 0x21; //"!" + private static final int EOL = 0x0A; //"\n" + private static final byte[] EOD = {0x7E, 0x3E}; //"~>" + + private static final long BASE85_4 = 85; + private static final long BASE85_3 = BASE85_4 * BASE85_4; + private static final long BASE85_2 = BASE85_3 * BASE85_4; + private static final long BASE85_1 = BASE85_2 * BASE85_4; + + private static final boolean DEBUG = false; + + private int pos = 0; + private long buffer = 0; + private int posinline = 0; + private int bw = 0; + + + /** @see java.io.FilterOutputStream **/ + public ASCII85OutputStream(OutputStream out) { + super(out); + } + + + /** @see java.io.FilterOutputStream **/ + public void write(int b) throws IOException { + if (pos == 0) { + buffer += (b << 24) & 0xff000000L; + } else if (pos == 1) { + buffer += (b << 16) & 0xff0000L; + } else if (pos == 2) { + buffer += (b << 8) & 0xff00L; + } else { + buffer += b & 0xffL; + } + pos++; + + if (pos > 3) { + checkedWrite(convertWord(buffer)); + buffer = 0; + pos = 0; + } + } + + + private void checkedWrite(int b) throws IOException { + if (posinline == 80) { + out.write(EOL); bw++; + posinline = 0; + } + checkedWrite(b); + posinline++; + bw++; + } + + + private void checkedWrite(byte[] buf) throws IOException { + checkedWrite(buf, buf.length); + } + + + private void checkedWrite(byte[] buf , int len) throws IOException { + if (posinline + len > 80) { + int firstpart = len - (posinline + len - 80); + if (firstpart > 0) { + out.write(buf, 0, firstpart); + } + out.write(EOL); bw++; + int rest = len - firstpart; + if (rest > 0) { + out.write(buf, firstpart, rest); + } + posinline = rest; + } else { + out.write(buf, 0, len); + posinline += len; + } + bw += len; + } + + + /** + * This converts a 32 bit value (4 bytes) into 5 bytes using base 85. + * each byte in the result starts with zero at the '!' character so + * the resulting base85 number fits into printable ascii chars + * + * @param word the 32 bit unsigned (hence the long datatype) word + * @return 5 bytes (or a single byte of the 'z' character for word + * values of 0) + */ + private byte[] convertWord(long word) { + word = word & 0xffffffff; + + if (word == 0) { + return ZERO_ARRAY; + } else { + if (word < 0) { + word = -word; + } + byte c1 = (byte)((word / BASE85_1) & 0xFF); + byte c2 = (byte)(((word - (c1 * BASE85_1)) / BASE85_2) & 0xFF); + byte c3 = + (byte)(((word - (c1 * BASE85_1) - (c2 * BASE85_2)) + / BASE85_3) & 0xFF); + byte c4 = + (byte)(((word - (c1 * BASE85_1) - (c2 * BASE85_2) - (c3 * BASE85_3)) + / BASE85_4) & 0xFF); + byte c5 = + (byte)(((word - (c1 * BASE85_1) - (c2 * BASE85_2) - (c3 * BASE85_3) + - (c4 * BASE85_4))) + & 0xFF); + + byte[] ret = { + (byte)(c1 + START), (byte)(c2 + START), + (byte)(c3 + START), (byte)(c4 + START), + (byte)(c5 + START) + }; + + if (DEBUG) { + for (int i = 0; i < ret.length; i++) { + if (ret[i] < 33 || ret[i] > 117) { + System.out.println("Illegal char value " + + new Integer(ret[i])); + } + } + } + return ret; + } + } + + + /** @see org.apache.fop.render.ps.Finalizable **/ + public void finalizeStream() throws IOException { + // now take care of the trailing few bytes. + // with n leftover bytes, we append 0 bytes to make a full group of 4 + // then convert like normal (except not applying the special zero rule) + // and write out the first n+1 bytes from the result + if (pos > 0) { + int rest = pos; + /* + byte[] lastdata = new byte[4]; + int i = 0; + for (int j = 0; j < 4; j++) { + if (j < rest) { + lastdata[j] = data[i++]; + } else { + lastdata[j] = 0; + } + } + + long val = ((lastdata[0] << 24) & 0xff000000L) + + ((lastdata[1] << 16) & 0xff0000L) + + ((lastdata[2] << 8) & 0xff00L) + + (lastdata[3] & 0xffL); + */ + + byte[] conv; + // special rule for handling zeros at the end + if (buffer != 0) { + conv = convertWord(buffer); + } else { + conv = new byte[5]; + for (int j = 0; j < 5; j++) { + conv[j] = (byte)'!'; + } + } + // assert rest+1 <= 5 + checkedWrite(conv, rest + 1); + } + // finally write the two character end of data marker + checkedWrite(EOD); + + flush(); + if (out instanceof Finalizable) { + ((Finalizable)out).finalizeStream(); + } + } + + + /** @see java.io.FilterOutputStream **/ + public void close() throws IOException { + finalizeStream(); + super.close(); + } + +} + + diff --git a/src/java/org/apache/fop/render/ps/ASCIIHexOutputStream.java b/src/java/org/apache/fop/render/ps/ASCIIHexOutputStream.java new file mode 100644 index 000000000..1be3766b0 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/ASCIIHexOutputStream.java @@ -0,0 +1,134 @@ +/* + * $Id: ASCIIHexOutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.OutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; + +/** + * This class applies a ASCII Hex encoding to the stream. + * + * @author Jeremias Maerki + * @version $Id: ASCIIHexOutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + */ +public class ASCIIHexOutputStream extends FilterOutputStream + implements Finalizable { + + private static final int EOL = 0x0A; //"\n" + private static final int EOD = 0x3E; //">" + private static final int ZERO = 0x30; //"0" + private static final int NINE = 0x39; //"9" + private static final int A = 0x41; //"A" + private static final int ADIFF = A - NINE - 1; + + private int posinline = 0; + + + /** @see java.io.FilterOutputStream **/ + public ASCIIHexOutputStream(OutputStream out) { + super(out); + } + + + /** @see java.io.FilterOutputStream **/ + public void write(int b) throws IOException { + b &= 0xFF; + + int digit1 = ((b & 0xF0) >> 4) + ZERO; + if (digit1 > NINE) { + digit1 += ADIFF; + } + out.write(digit1); + + int digit2 = (b & 0x0F) + ZERO; + if (digit2 > NINE) { + digit2 += ADIFF; + } + out.write(digit2); + + posinline++; + checkLineWrap(); + } + + + private void checkLineWrap() throws IOException { + //Maximum line length is 80 characters + if (posinline >= 40) { + out.write(EOL); + posinline = 0; + } + } + + + /** @see org.apache.fop.render.ps.Finalizable **/ + public void finalizeStream() throws IOException { + checkLineWrap(); + //Write closing character ">" + super.write(EOD); + + flush(); + if (out instanceof Finalizable) { + ((Finalizable) out).finalizeStream(); + } + } + + + /** @see java.io.FilterOutputStream **/ + public void close() throws IOException { + finalizeStream(); + super.close(); + } + + +} + + diff --git a/src/java/org/apache/fop/render/ps/DSCConstants.java b/src/java/org/apache/fop/render/ps/DSCConstants.java new file mode 100644 index 000000000..fcaee2ac9 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/DSCConstants.java @@ -0,0 +1,202 @@ +/* + * $Id: DSCConstants.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +/** + * This class defines constants with Strings for the DSC specification. + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id: DSCConstants.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + */ +public class DSCConstants { + + // ----==== General Header Comments ====---- + + /** Lead-in for a DSC-conformant PostScript file */ + public static final String PS_ADOBE_30 = "%!PS-Adobe-3.0"; + + /** Bounding box for the document */ + public static final String BBOX = "BoundingBox"; + /** Copyright information associated with the document or resource */ + public static final String COPYRIGHT = "Copyright"; + /** Creator of the document */ + public static final String CREATOR = "Creator"; + /** Date and time when the document was created */ + public static final String CREATION_DATE = "CreationDate"; + /** Type of data */ + public static final String DOCUMENT_DATA = "BoundingBox"; + /** Use for inidicating an emulator being invoked in the document */ + public static final String EMULATION = "Emulation"; + /** Explicit end of comments */ + public static final String END_COMMENTS = "EndComments"; + /** Required PostScript Level 1 extension for this document */ + public static final String EXTENSIONS = "Extensions"; + /** Indicates who is this document printed for */ + public static final String FOR = "For"; + /** Indicates the PostScript language level used in the document */ + public static final String LANGUAGE_LEVEL = "LanguageLevel"; + /** Indicates the orientation of the document */ + public static final String ORIENTATION = "Orientation"; + /** Number of pages in the document */ + public static final String PAGES = "Pages"; + /** Indicates the order of the pages */ + public static final String PAGE_ORDER = "PageOrder"; + /** Indicates how the document should be routed back to its owner */ + public static final String ROUTING = "Routing"; + /** Title of the document */ + public static final String TITLE = "Title"; + /** Version of the document */ + public static final String VERSION = "Version"; + + // ----==== General Body Comments ====---- + + /** Indicates a continued line */ + public static final String NEXT_LINE = "+ "; + + //Skipping BeginBinary/EndBinary. They are deprecated. + + /** Indicates the start of a data section*/ + public static final String BEGIN_DATA = "BeginData"; + /** Indicates the end of a data section*/ + public static final String END_DATA = "EndData"; + + /** Indicates the start of the defaults section */ + public static final String BEGIN_DEFAULTS = "BeginDefaults"; + /** Indicates the end of the defaults section */ + public static final String END_DEFAULTS = "EndDefaults"; + + /** Indicates the start of a non-PostScript section */ + public static final String BEGIN_EMULATION = "BeginEmulation"; + /** Indicates the end of a non-PostScript section */ + public static final String END_EMULATION = "EndEmulation"; + + /** Indicates the start of a preview section (EPS only)*/ + public static final String BEGIN_PREVIEW = "BeginPreview"; + /** Indicates the end of a preview section (EPS only)*/ + public static final String END_PREVIEW = "EndPreview"; + + /** Indicates the start of the prolog */ + public static final String BEGIN_PROLOG = "BeginProlog"; + /** Indicates the end of the prolog */ + public static final String END_PROLOG = "EndProlog"; + + /** Indicates the start of the document setup */ + public static final String BEGIN_SETUP = "BeginSetup"; + /** Indicates the end of the document setup */ + public static final String END_SETUP = "EndSetup"; + + + // ----==== General Page Comments ====---- + + /** Indicates the start of a graphic object */ + public static final String BEGIN_OBJECT = "BeginObject"; + /** Indicates the end of a graphic object */ + public static final String END_OBJECT = "EndObject"; + + /** Indicates the start of the page setup section */ + public static final String BEGIN_PAGE_SETUP = "BeginPageSetup"; + /** Indicates the end of the page setup section */ + public static final String END_PAGE_SETUP = "EndPageSetup"; + + /** Indicates a page number */ + public static final String PAGE = "Page"; + /** Bounding box for a page */ + public static final String PAGE_BBOX = "PageBoundingBox"; + /** Bounding box for a page */ + public static final String PAGE_ORIENTATION = "PageOrientation"; + + + // ----==== General Trailer Comments ====---- + + /** Indicates the start of the page trailer */ + public static final String PAGE_TRAILER = "PageTrailer"; + /** Indicates the start of the document trailer */ + public static final String TRAILER = "Trailer"; + /** Indicates the end of a page (NON-STANDARD!) */ + public static final String END_PAGE = "EndPage"; + /** Indicates the end of the document */ + public static final String EOF = "EOF"; + + + // ----==== Requirements Conventions ====---- + + /**@todo Add the missing comments */ + + // ----==== Requirement Body Comments ====---- + + /** Indicates the start of an embedded document */ + public static final String BEGIN_DOCUMENT = "BeginDocument"; + /** Indicates the end of an embedded document */ + public static final String END_DOCUMENT = "EndDocument"; + /** Indicates a referenced embedded document */ + public static final String INCLUDE_DOCUMENT = "IncludeDocument"; + + /** Indicates the start of a PPD feature */ + public static final String BEGIN_FEATURE = "BeginFeature"; + /** Indicates the end of a PPD feature */ + public static final String END_FEATURE = "EndFeature"; + /** Indicates a referenced a PPD feature */ + public static final String INCLUDE_FEATURE = "IncludeFeature"; + + //Skipping BeginFile/EndFile/IncludeFile. They are deprecated. + //Skipping BeginFont/EndFont/IncludeFont. They are deprecated. + //Skipping BeginProcSet/EndProcSet/IncludeProcSet. They are deprecated. + + /** Indicates the start of a resource (font, file, procset) */ + public static final String BEGIN_RESOURCE = "BeginResource"; + /** Indicates the end of a resource (font, file, procset) */ + public static final String END_RESOURCE = "EndResource"; + /** Indicates a referenced a resource (font, file, procset) */ + public static final String INCLUDE_RESOURCE = "IncludeResource"; + + +} diff --git a/src/java/org/apache/fop/render/ps/Finalizable.java b/src/java/org/apache/fop/render/ps/Finalizable.java new file mode 100644 index 000000000..af07bdfd6 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/Finalizable.java @@ -0,0 +1,74 @@ +/* + * $Id: Finalizable.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +/** + * This interface is used for special FilteredOutputStream classes that won't + * be closed (since this causes the target OutputStream to be closed, too) but + * where flush() is not enough, for example because a final marker has to be + * written to the target stream. + * + * @author Jeremias Maerki + * @version $Id: Finalizable.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + */ +public interface Finalizable { + + /** + * This method can be called instead of close() on a subclass of + * FilteredOutputStream when a final marker has to be written to the target + * stream, but close() cannot be called. + * + * @exception java.io.IOException In case of an IO problem + */ + void finalizeStream() + throws java.io.IOException; + +} diff --git a/src/java/org/apache/fop/render/ps/FlateEncodeOutputStream.java b/src/java/org/apache/fop/render/ps/FlateEncodeOutputStream.java new file mode 100644 index 000000000..3ebb7726c --- /dev/null +++ b/src/java/org/apache/fop/render/ps/FlateEncodeOutputStream.java @@ -0,0 +1,85 @@ +/* + * $Id: FlateEncodeOutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.OutputStream; +import java.io.IOException; + +/** + * This class applies a FlateEncode filter to the stream. It is basically the + * normal DeflaterOutputStream except now also implementing the Finalizable + * interface. + * + * @author Jeremias Maerki + * @version $Id: FlateEncodeOutputStream.java,v 1.4 2003/03/07 09:46:30 jeremias Exp $ + */ +public class FlateEncodeOutputStream extends java.util.zip.DeflaterOutputStream + implements Finalizable { + + + /** @see java.util.zip.DeflaterOutputStream **/ + public FlateEncodeOutputStream(OutputStream out) { + super(out); + } + + + /** @see org.apache.fop.render.ps.Finalizable **/ + public void finalizeStream() throws IOException { + finish(); + flush(); + if (out instanceof Finalizable) { + ((Finalizable)out).finalizeStream(); + } + } + +} + + diff --git a/src/java/org/apache/fop/render/ps/PSGenerator.java b/src/java/org/apache/fop/render/ps/PSGenerator.java new file mode 100644 index 000000000..2b0622d96 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSGenerator.java @@ -0,0 +1,371 @@ +/* + * $Id: PSGenerator.java,v 1.3 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.OutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.Date; +import java.util.Stack; + +/** + * This class is used to output PostScript code to an OutputStream. + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id: PSGenerator.java,v 1.3 2003/03/07 09:46:30 jeremias Exp $ + */ +public class PSGenerator { + + /** + * Indicator for the PostScript interpreter that the value is provided + * later in the document (mostly in the %%Trailer section). + */ + public static final AtendIndicator ATEND = new AtendIndicator() {}; + + private OutputStream out; + + private Stack graphicsStateStack = new Stack(); + private PSState currentState; + + private StringBuffer tempBuffer = new StringBuffer(256); + + /** @see java.io.FilterOutputStream **/ + public PSGenerator(OutputStream out) { + this.out = out; + this.currentState = new PSState(); + this.graphicsStateStack.push(this.currentState); + } + + /** + * Writes a newline character to the OutputStream. + * + * @throws IOException In case of an I/O problem + */ + public final void newLine() throws IOException { + out.write('\n'); + } + + /** + * Formats a double value for PostScript output. + * + * @param value value to format + * @return the formatted value + */ + public String formatDouble(double value) { + NumberFormat nf = new java.text.DecimalFormat("0.#"); + return nf.format(value); + } + + /** + * Writes a PostScript command to the stream. + * + * @param cmd The PostScript code to be written. + * @exception IOException In case of an I/O problem + */ + public void write(String cmd) throws IOException { + if (cmd.length() > 255) { + throw new RuntimeException("PostScript command exceeded limit of 255 characters"); + } + out.write(cmd.getBytes("US-ASCII")); + } + + /** + * Writes a PostScript command to the stream and ends the line. + * + * @param cmd The PostScript code to be written. + * @exception IOException In case of an I/O problem + */ + public void writeln(String cmd) throws IOException { + write(cmd); + newLine(); + } + + /** + * Writes encoded data to the PostScript stream. + * + * @param cmd The encoded PostScript code to be written. + * @exception IOException In case of an I/O problem + */ + public void writeByteArr(byte[] cmd) throws IOException { + out.write(cmd); + newLine(); + } + + + /** + * Flushes the OutputStream. + * + * @exception IOException In case of an I/O problem + */ + public void flush() throws IOException { + out.flush(); + } + + + /** + * Escapes a character conforming to the rules established in the PostScript + * Language Reference (Search for "Literal Text Strings"). + * @param c character to escape + * @param target target StringBuffer to write the escaped character to + */ + public static final void escapeChar(char c, StringBuffer target) { + if (c > 127) { + target.append("\\"); + target.append(Integer.toOctalString(c)); + } else { + switch (c) { + case '\n': + target.append("\\n"); + break; + case '\r': + target.append("\\r"); + break; + case '\t': + target.append("\\t"); + break; + case '\b': + target.append("\\b"); + break; + case '\f': + target.append("\\f"); + break; + case '\\': + target.append("\\\\"); + break; + case '(': + target.append("\\("); + break; + case ')': + target.append("\\)"); + break; + default: + target.append(c); + } + } + } + + + /** + * Converts text by applying escaping rules established in the DSC specs. + * @param text Text to convert + * @return String The resulting String + */ + public static final String convertStringToDSC(String text) { + return convertStringToDSC(text, false); + } + + + /** + * Converts text by applying escaping rules established in the DSC specs. + * @param text Text to convert + * @param forceParentheses Force the use of parentheses + * @return String The resulting String + */ + public static final String convertStringToDSC(String text, + boolean forceParentheses) { + if ((text == null) || (text.length() == 0)) { + return "()"; + } else { + int initialSize = text.length(); + initialSize += initialSize / 2; + StringBuffer sb = new StringBuffer(initialSize); + if ((Long.getLong(text) != null) + || (text.indexOf(" ") >= 0) + || forceParentheses) { + + sb.append("("); + for (int i = 0; i < text.length(); i++) { + final char c = text.charAt(i); + escapeChar(c, sb); + } + sb.append(")"); + return sb.toString(); + } else { + return text; + } + } + } + + + /** + * Writes a DSC comment to the output stream. + * @param name Name of the DSC comment + * @exception IOException In case of an I/O problem + * @see org.apache.fop.render.ps.DSCConstants + */ + public void writeDSCComment(String name) throws IOException { + writeln("%%" + name); + } + + + /** + * Writes a DSC comment to the output stream. The parameter to the DSC + * comment can be any object. The object is converted to a String as + * necessary. + * @param name Name of the DSC comment + * @param param Single parameter to the DSC comment + * @exception IOException In case of an I/O problem + * @see org.apache.fop.render.ps.DSCConstants + */ + public void writeDSCComment(String name, Object param) throws IOException { + writeDSCComment(name, new Object[] {param}); + } + + + /** + * Writes a DSC comment to the output stream. The parameters to the DSC + * comment can be any object. The objects are converted to Strings as + * necessary. Please see the source code to find out what parameters are + * currently supported. + * @param name Name of the DSC comment + * @param params Array of parameters to the DSC comment + * @exception IOException In case of an I/O problem + * @see org.apache.fop.render.ps.DSCConstants + */ + public void writeDSCComment(String name, Object[] params) throws IOException { + tempBuffer.setLength(0); + tempBuffer.append("%%"); + tempBuffer.append(name); + if ((params != null) && (params.length > 0)) { + tempBuffer.append(": "); + for (int i = 0; i < params.length; i++) { + if (i > 0) { + tempBuffer.append(" "); + } + + if (params[i] instanceof String) { + tempBuffer.append(convertStringToDSC((String)params[i])); + } else if (params[i] instanceof AtendIndicator) { + tempBuffer.append("(atend)"); + } else if (params[i] instanceof Number) { + tempBuffer.append(params[i].toString()); + } else if (params[i] instanceof Date) { + DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + tempBuffer.append(convertStringToDSC(df.format((Date)params[i]))); + } else { + throw new IllegalArgumentException("Unsupported parameter type: " + + params[i].getClass().getName()); + } + } + } + writeln(tempBuffer.toString()); + } + + + /** + * Saves the graphics state of the rendering engine. + * @exception IOException In case of an I/O problem + */ + public void saveGraphicsState() throws IOException { + writeln("gsave"); + + PSState state = (PSState)this.currentState.clone(); + this.graphicsStateStack.push(this.currentState); + this.currentState = state; + } + + /** + * Restores the last graphics state of the rendering engine. + * @exception IOException In case of an I/O problem + */ + public void restoreGraphicsState() throws IOException { + writeln("grestore"); + this.currentState = (PSState)this.graphicsStateStack.pop(); + } + + /** + * Concats the transformation matrix. + * @param a A part + * @param b B part + * @param c C part + * @param d D part + * @param e E part + * @param f F part + * @exception IOException In case of an I/O problem + */ + public void concatMatrix(double a, double b, + double c, double d, + double e, double f) throws IOException { + writeln("[" + formatDouble(a) + " " + + formatDouble(b) + " " + + formatDouble(c) + " " + + formatDouble(d) + " " + + formatDouble(e) + " " + + formatDouble(f) + "] concat"); + } + + /** + * Concats the transformations matrix. + * @param matrix Matrix to use + * @exception IOException In case of an I/O problem + */ + public void concatMatrix(double[] matrix) throws IOException { + concatMatrix(matrix[0], matrix[1], + matrix[2], matrix[3], + matrix[4], matrix[5]); + } + + /** + * Returns the current graphics state. + * @return the current graphics state + */ + public PSState getCurrentState() { + return this.currentState; + } + + + /** Used for the ATEND constant. See there. */ + private static interface AtendIndicator { + } + +} diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2D.java b/src/java/org/apache/fop/render/ps/PSGraphics2D.java new file mode 100644 index 000000000..9a2908422 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSGraphics2D.java @@ -0,0 +1,1134 @@ +/* + * $Id: PSGraphics2D.java,v 1.11 2003/03/11 08:42:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +//Java +import java.util.List; +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.TexturePaint; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.ImageObserver; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.io.IOException; + +// FOP +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; + +// Batik +import org.apache.batik.ext.awt.g2d.AbstractGraphics2D; +import org.apache.batik.ext.awt.g2d.GraphicContext; + + +/** + * This concrete implementation of AbstractGraphics2D is a + * simple help to programmers to get started with their own + * implementation of Graphics2D. + * DefaultGraphics2D implements all the abstract methods + * is AbstractGraphics2D and makes it easy to start + * implementing a Graphic2D piece-meal. + * + * @author Keiron Liddle + * @version $Id: PSGraphics2D.java,v 1.11 2003/03/11 08:42:24 jeremias Exp $ + * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D + */ +public class PSGraphics2D extends AbstractGraphics2D { + + private boolean standalone = false; + + /** + * the PostScript genertaor being created + */ + protected PSGenerator gen; + + /** Currently valid FontState */ + protected FontState fontState; + + /** Overriding FontState */ + protected FontState overrideFontState = null; + + /** + * the current (internal) font name + */ + protected String currentFontName; + + /** + * the current font size in millipoints + */ + protected int currentFontSize; + + /** + * the current vertical position in millipoints from bottom + */ + protected int currentYPosition = 0; + + /** + * the current horizontal position in millipoints from left + */ + protected int currentXPosition = 0; + + /** + * the current colour for use in svg + */ + protected Color currentColour = new Color(0, 0, 0); + + /** FontInfo containing all available fonts */ + protected FontInfo fontInfo; + + /** + * Create a new Graphics2D that generates PostScript code. + * @param textAsShapes True if text should be rendered as graphics + * @param gen PostScript generator to use for output + * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) + */ + public PSGraphics2D(boolean textAsShapes, PSGenerator gen) { + super(textAsShapes); + this.gen = gen; + } + + /** + * Constructor for creating copies + * @param g parent PostScript Graphics2D + */ + public PSGraphics2D(PSGraphics2D g) { + super(g); + } + + /** + * Sets the GraphicContext + * @param c GraphicContext to use + */ + public void setGraphicContext(GraphicContext c) { + gc = c; + } + + /** + * Creates a new Graphics object that is + * a copy of this Graphics object. + * @return a new graphics context that is a copy of + * this graphics context. + */ + public Graphics create() { + return new PSGraphics2D(this); + } + + /** + * Central handler for IOExceptions for this class. + * @param ioe IOException to handle + */ + protected void handleIOException(IOException ioe) { + ioe.printStackTrace(); + } + + /** + * Draws as much of the specified image as is currently available. + * The image is drawn with its top-left corner at + * (xy) in this graphics context's coordinate + * space. Transparent pixels in the image do not affect whatever + * pixels are already there. + *

+ * This method returns immediately in all cases, even if the + * complete image has not yet been loaded, and it has not been dithered + * and converted for the current output device. + *

+ * If the image has not yet been completely loaded, then + * drawImage returns false. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * @param img the specified image to be drawn. + * @param x the x coordinate. + * @param y the y coordinate. + * @param observer object to be notified as more of + * the image is converted. + * @return True if the image has been fully drawn/loaded + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + ImageObserver observer) { + // System.err.println("drawImage:x, y"); + + final int width = img.getWidth(observer); + final int height = img.getHeight(observer); + if (width == -1 || height == -1) { + return false; + } + + Dimension size = new Dimension(width, height); + BufferedImage buf = buildBufferedImage(size); + + java.awt.Graphics2D g = buf.createGraphics(); + g.setComposite(AlphaComposite.SrcOver); + g.setBackground(new Color(1, 1, 1, 0)); + g.setPaint(new Color(1, 1, 1, 0)); + g.fillRect(0, 0, width, height); + g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); + + if (!g.drawImage(img, 0, 0, observer)) { + return false; + } + g.dispose(); + + final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3]; + //final byte[] mask = new byte[buf.getWidth() * buf.getHeight()]; + + Raster raster = buf.getData(); + DataBuffer bd = raster.getDataBuffer(); + + int count = 0; + //int maskpos = 0; + switch (bd.getDataType()) { + case DataBuffer.TYPE_INT: + int[][] idata = ((DataBufferInt)bd).getBankData(); + for (int i = 0; i < idata.length; i++) { + for (int j = 0; j < idata[i].length; j++) { + // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF); + if (((idata[i][j] >> 24) & 0xFF) != 255) { + result[count++] = (byte)0xFF; + result[count++] = (byte)0xFF; + result[count++] = (byte)0xFF; + } else { + result[count++] = (byte)((idata[i][j] >> 16) & 0xFF); + result[count++] = (byte)((idata[i][j] >> 8) & 0xFF); + result[count++] = (byte)((idata[i][j]) & 0xFF); + } + } + } + break; + default: + // error + break; + } + + /*try { + FopImage fopimg = new TempImage(width, height, result, mask); + AffineTransform at = getTransform(); + double[] matrix = new double[6]; + at.getMatrix(matrix); + psRenderer.write("gsave"); + Shape imclip = getClip(); + writeClip(imclip); + // psRenderer.write("" + matrix[0] + " " + matrix[1] + + // " " + matrix[2] + " " + matrix[3] + " " + + // matrix[4] + " " + matrix[5] + " cm\n"); + //psRenderer.renderBitmap(fopimg, x, y, width, height); + psRenderer.write("grestore"); + } catch (Exception e) { + e.printStackTrace(); + }*/ + return true; + } + + /** + * Creates a buffered image. + * @param size dimensions of the image to be created + * @return the buffered image + */ + public BufferedImage buildBufferedImage(Dimension size) { + return new BufferedImage(size.width, size.height, + BufferedImage.TYPE_INT_ARGB); + } + + /*class TempImage implements FopImage { + int m_height; + int m_width; + int m_bitsPerPixel; + PDFColorSpace m_colorSpace; + int m_bitmapSiye; + byte[] m_bitmaps; + byte[] m_mask; + PDFColor transparent = new PDFColor(255, 255, 255); + + TempImage(int width, int height, byte[] result, + byte[] mask) { + this.m_height = height; + this.m_width = width; + this.m_bitsPerPixel = 8; + this.m_colorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + // this.m_isTransparent = false; + // this.m_bitmapsSize = this.m_width * this.m_height * 3; + this.m_bitmaps = result; + this.m_mask = mask; + } + + public boolean load(int type, FOUserAgent ua) { + return true; + } + + public String getMimeType() { + return ""; + } + + public String getURL() { + return "" + m_bitmaps; + } + + // image size + public int getWidth() { + return m_width; + } + + public int getHeight() { + return m_height; + } + + // DeviceGray, DeviceRGB, or DeviceCMYK + public PDFColorSpace getColorSpace() { + return m_colorSpace; + } + + // bits per pixel + public int getBitsPerPixel() { + return m_bitsPerPixel; + } + + // For transparent images + public boolean isTransparent() { + return transparent != null; + } + + public PDFColor getTransparentColor() { + return transparent; + } + + public boolean hasSoftMask() { + return m_mask != null; + } + + public byte[] getSoftMask() { + return m_mask; + } + + // get the image bytes, and bytes properties + + // get uncompressed image bytes + public byte[] getBitmaps() { + return m_bitmaps; + } + + // width * (bitsPerPixel / 8) * height, no ? + public int getBitmapsSize() { + return m_width * m_height * 3; + } + + // get compressed image bytes + // I don't know if we really need it, nor if it + // should be changed... + public byte[] getRessourceBytes() { + return null; + } + + public int getRessourceBytesSize() { + return 0; + } + + // return null if no corresponding PDFFilter + public PDFFilter getPDFFilter() { + return null; + } + + // release memory + public void close() {} + + }*/ + + + /** + * Draws as much of the specified image as has already been scaled + * to fit inside the specified rectangle. + *

+ * The image is drawn inside the specified rectangle of this + * graphics context's coordinate space, and is scaled if + * necessary. Transparent pixels do not affect whatever pixels + * are already there. + *

+ * This method returns immediately in all cases, even if the + * entire image has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete, then + * drawImage returns false. As more of + * the image becomes available, the process that draws the image notifies + * the image observer by calling its imageUpdate method. + *

+ * A scaled version of an image will not necessarily be + * available immediately just because an unscaled version of the + * image has been constructed for this output device. Each size of + * the image may be cached separately and generated from the original + * data in a separate image production sequence. + * @param img the specified image to be drawn. + * @param x the x coordinate. + * @param y the y coordinate. + * @param width the width of the rectangle. + * @param height the height of the rectangle. + * @param observer object to be notified as more of + * the image is converted. + * @return True if the image has been fully loaded/drawn + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { + System.out.println("drawImage"); + return true; + } + + /** + * Disposes of this graphics context and releases + * any system resources that it is using. + * A Graphics object cannot be used after + * disposehas been called. + *

+ * When a Java program runs, a large number of Graphics + * objects can be created within a short time frame. + * Although the finalization process of the garbage collector + * also disposes of the same system resources, it is preferable + * to manually free the associated resources by calling this + * method rather than to rely on a finalization process which + * may not run to completion for a long period of time. + *

+ * Graphics objects which are provided as arguments to the + * paint and update methods + * of components are automatically released by the system when + * those methods return. For efficiency, programmers should + * call dispose when finished using + * a Graphics object only if it was created + * directly from a component or another Graphics object. + * @see java.awt.Graphics#finalize + * @see java.awt.Component#paint + * @see java.awt.Component#update + * @see java.awt.Component#getGraphics + * @see java.awt.Graphics#create + */ + public void dispose() { + // System.out.println("dispose"); + this.gen = null; + fontState = null; + currentFontName = null; + currentColour = null; + fontInfo = null; + } + + /** + * Strokes the outline of a Shape using the settings of the + * current Graphics2D context. The rendering attributes + * applied include the Clip, Transform, + * Paint, Composite and + * Stroke attributes. + * @param s the Shape to be rendered + * @see #setStroke + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #transform + * @see #setTransform + * @see #clip + * @see #setClip + * @see #setComposite + */ + public void draw(Shape s) { + try { + // System.out.println("draw(Shape)"); + gen.saveGraphicsState(); + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + gen.writeln(gen.formatDouble(c.getRed() / 255.0) + " " + + gen.formatDouble(c.getGreen() / 255.0) + " " + + gen.formatDouble(c.getBlue() / 255.0) + " setrgbcolor"); + + applyPaint(getPaint(), false); + applyStroke(getStroke()); + + gen.writeln("newpath"); + PathIterator iter = s.getPathIterator(getTransform()); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " " + + gen.formatDouble(1000 * vals[4]) + " " + + gen.formatDouble(1000 * vals[5]) + + " curveto"); + break; + case PathIterator.SEG_LINETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " lineto"); + break; + case PathIterator.SEG_MOVETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " M"); + break; + case PathIterator.SEG_QUADTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " QUADTO "); + break; + case PathIterator.SEG_CLOSE: + gen.writeln("closepath"); + break; + default: + break; + } + iter.next(); + } + doDrawing(false, true, false); + gen.restoreGraphicsState(); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Establishes a clipping region + * @param s Shape defining the clipping region + */ + protected void writeClip(Shape s) { + try { + PathIterator iter = s.getPathIterator(getTransform()); + gen.writeln("newpath"); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " " + + gen.formatDouble(1000 * vals[4]) + " " + + gen.formatDouble(1000 * vals[5]) + + " curveto"); + break; + case PathIterator.SEG_LINETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " lineto"); + break; + case PathIterator.SEG_MOVETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " M"); + break; + case PathIterator.SEG_QUADTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " QUADTO "); + break; + case PathIterator.SEG_CLOSE: + gen.writeln("closepath"); + break; + default: + break; + } + iter.next(); + } + // clip area + gen.writeln("clippath"); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Applies a new Paint object. + * @param paint Paint object to use + * @param fill True if to be applied for filling + */ + protected void applyPaint(Paint paint, boolean fill) { + if (paint instanceof GradientPaint) { + GradientPaint gp = (GradientPaint)paint; + Color c1 = gp.getColor1(); + Color c2 = gp.getColor2(); + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + //boolean cyclic = gp.isCyclic(); + + List theCoords = new java.util.ArrayList(); + theCoords.add(new Double(p1.getX())); + theCoords.add(new Double(p1.getY())); + theCoords.add(new Double(p2.getX())); + theCoords.add(new Double(p2.getY())); + + List theExtend = new java.util.ArrayList(); + theExtend.add(new Boolean(true)); + theExtend.add(new Boolean(true)); + + List theDomain = new java.util.ArrayList(); + theDomain.add(new Double(0)); + theDomain.add(new Double(1)); + + List theEncode = new java.util.ArrayList(); + theEncode.add(new Double(0)); + theEncode.add(new Double(1)); + theEncode.add(new Double(0)); + theEncode.add(new Double(1)); + + List theBounds = new java.util.ArrayList(); + theBounds.add(new Double(0)); + theBounds.add(new Double(1)); + + //List theFunctions = new java.util.ArrayList(); + + List someColors = new java.util.ArrayList(); + + Color color1 = new Color(c1.getRed(), c1.getGreen(), + c1.getBlue()); + someColors.add(color1); + Color color2 = new Color(c2.getRed(), c2.getGreen(), + c2.getBlue()); + someColors.add(color2); + + //PDFColorSpace aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + } else if (paint instanceof TexturePaint) { + //nop + } + } + + /** + * Applies a new Stroke object. + * @param stroke Stroke object to use + */ + protected void applyStroke(Stroke stroke) { + try { + if (stroke instanceof BasicStroke) { + BasicStroke bs = (BasicStroke)stroke; + + float[] da = bs.getDashArray(); + if (da != null) { + gen.writeln("["); + for (int count = 0; count < da.length; count++) { + gen.writeln("" + (1000 * (int)da[count])); + if (count < da.length - 1) { + gen.writeln(" "); + } + } + gen.writeln("] "); + float offset = bs.getDashPhase(); + gen.writeln((1000 * (int)offset) + " setdash"); + } + int ec = bs.getEndCap(); + switch (ec) { + case BasicStroke.CAP_BUTT: + gen.writeln(0 + " setlinecap"); + break; + case BasicStroke.CAP_ROUND: + gen.writeln(1 + " setlinecap"); + break; + case BasicStroke.CAP_SQUARE: + gen.writeln(2 + " setlinecap"); + break; + } + + int lj = bs.getLineJoin(); + switch (lj) { + case BasicStroke.JOIN_MITER: + gen.writeln("0 setlinejoin"); + break; + case BasicStroke.JOIN_ROUND: + gen.writeln("1 setlinejoin"); + break; + case BasicStroke.JOIN_BEVEL: + gen.writeln("2 setlinejoin"); + break; + } + float lw = bs.getLineWidth(); + gen.writeln(gen.formatDouble(1000 * lw) + " setlinewidth"); + + float ml = bs.getMiterLimit(); + gen.writeln(gen.formatDouble(1000 * ml) + " setmiterlimit"); + } + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Renders a {@link RenderedImage}, + * applying a transform from image + * space into user space before drawing. + * The transformation from user space into device space is done with + * the current Transform in the Graphics2D. + * The specified transformation is applied to the image before the + * transform attribute in the Graphics2D context is applied. + * The rendering attributes applied include the Clip, + * Transform, and Composite attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + * @param img the image to be rendered + * @param xform the transformation from image space into user space + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + System.out.println("drawRenderedImage"); + } + + + /** + * Renders a + * {@link RenderableImage}, + * applying a transform from image space into user space before drawing. + * The transformation from user space into device space is done with + * the current Transform in the Graphics2D. + * The specified transformation is applied to the image before the + * transform attribute in the Graphics2D context is applied. + * The rendering attributes applied include the Clip, + * Transform, and Composite attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + *

+ * Rendering hints set on the Graphics2D object might + * be used in rendering the RenderableImage. + * If explicit control is required over specific hints recognized by a + * specific RenderableImage, or if knowledge of which hints + * are used is required, then a RenderedImage should be + * obtained directly from the RenderableImage + * and rendered using + * {@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. + * @param img the image to be rendered + * @param xform the transformation from image space into user space + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + * @see #drawRenderedImage + */ + public void drawRenderableImage(RenderableImage img, + AffineTransform xform) { + System.out.println("drawRenderableImage"); + } + + /** + * Renders the text specified by the specified String, + * using the current Font and Paint attributes + * in the Graphics2D context. + * The baseline of the first character is at position + * (xy) in the User Space. + * The rendering attributes applied include the Clip, + * Transform, Paint, Font and + * Composite attributes. For characters in script systems + * such as Hebrew and Arabic, the glyphs can be rendered from right to + * left, in which case the coordinate supplied is the location of the + * leftmost character on the baseline. + * @param s the String to be rendered + * @param x the x-coordinate where the String + * should be rendered + * @param y the y-coordinate where the String + * should be rendered + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see java.awt.Graphics#setFont + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(String s, float x, float y) { + try { + if (overrideFontState == null) { + Font gFont = getFont(); + String n = gFont.getFamily(); + if (n.equals("sanserif")) { + n = "sans-serif"; + } + int siz = gFont.getSize(); + String style = gFont.isItalic() ? "italic" : "normal"; + String weight = gFont.isBold() ? "bold" : "normal"; + + //try { + //fontState = new FontState(n, fontState.getFontMetrics(),siz); + //} catch (org.apache.fop.apps.FOPException fope) { + //fope.printStackTrace(); + //} + } else { + fontState = overrideFontState; + overrideFontState = null; + } + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + gen.writeln(c.getRed() / 255.0 + " " + + c.getGreen() / 255.0 + " " + + c.getBlue() / 255.0 + " setrgbcolor"); + + AffineTransform trans = getTransform(); + trans.translate(x, y); + double[] vals = new double[6]; + trans.getMatrix(vals); + gen.writeln(gen.formatDouble(1000 * vals[4]) + " " + + gen.formatDouble(1000 * vals[5]) + " moveto "); + //String fontWeight = fontState.getFontWeight(); + StringBuffer sb = new StringBuffer(); + + int l = s.length(); + + if ((currentFontName != fontState.getFontName()) + || (currentFontSize != fontState.getFontSize())) { + gen.writeln(fontState.getFontName() + " " + fontState.getFontSize() + " F"); + currentFontName = fontState.getFontName(); + currentFontSize = fontState.getFontSize(); + } + for (int i = 0; i < l; i++) { + char ch = s.charAt(i); + char mch = fontState.mapChar(ch); + if (mch > 127) { + sb = sb.append("\\" + Integer.toOctalString(mch)); + } else { + String escape = "\\()[]{}"; + if (escape.indexOf(mch) >= 0) { + sb.append("\\"); + } + sb = sb.append(mch); + } + } + + String psString = null; + psString = " (" + sb.toString() + ") " + " t "; + + gen.writeln(" 1.0 -1.0 scale"); + gen.writeln(psString); + gen.writeln(" 1.0 -1.0 scale"); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Renders the text of the specified iterator, using the + * Graphics2D context's current Paint. The + * iterator must specify a font + * for each character. The baseline of the + * first character is at position (xy) in the + * User Space. + * The rendering attributes applied include the Clip, + * Transform, Paint, and + * Composite attributes. + * For characters in script systems such as Hebrew and Arabic, + * the glyphs can be rendered from right to left, in which case the + * coordinate supplied is the location of the leftmost character + * on the baseline. + * @param iterator the iterator whose text is to be rendered + * @param x the x-coordinate where the iterator's text is to be + * rendered + * @param y the y-coordinate where the iterator's text is to be + * rendered + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + try { + System.err.println("drawString(AttributedCharacterIterator)"); + + gen.writeln("BT"); + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + currentColour = new Color(c.getRed(), c.getGreen(), c.getBlue()); + //gen.writeln(currentColour.getColorSpaceOut(true)); + c = getBackground(); + Color col = new Color(c.getRed(), c.getGreen(), c.getBlue()); + //gen.writeln(col.getColorSpaceOut(false)); + + AffineTransform trans = getTransform(); + trans.translate(x, y); + double[] vals = new double[6]; + trans.getMatrix(vals); + + for (char ch = iterator.first(); ch != CharacterIterator.DONE; + ch = iterator.next()) { + //Map attr = iterator.getAttributes(); + + gen.writeln(gen.formatDouble(vals[0]) + " " + + gen.formatDouble(vals[1]) + " " + + gen.formatDouble(vals[2]) + " " + + gen.formatDouble(vals[3]) + " " + + gen.formatDouble(vals[4]) + " " + + gen.formatDouble(vals[5]) + " " + + gen.formatDouble(vals[6]) + " Tm [" + ch + + "]"); + } + + gen.writeln("ET"); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Fills the interior of a Shape using the settings of the + * Graphics2D context. The rendering attributes applied + * include the Clip, Transform, + * Paint, and Composite. + * @param s the Shape to be filled + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void fill(Shape s) { + try { + // System.err.println("fill"); + gen.writeln("gsave"); + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + gen.writeln(gen.formatDouble(c.getRed() / 255.0) + " " + + gen.formatDouble(c.getGreen() / 255.0) + " " + + gen.formatDouble(c.getBlue() / 255.0) + " setrgbcolor"); + + applyPaint(getPaint(), true); + + gen.writeln("newpath"); + PathIterator iter = s.getPathIterator(getTransform()); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " " + + gen.formatDouble(1000 * vals[4]) + " " + + gen.formatDouble(1000 * vals[5]) + + " curveto"); + break; + case PathIterator.SEG_LINETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " lineto"); + break; + case PathIterator.SEG_MOVETO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + + " M"); + break; + case PathIterator.SEG_QUADTO: + gen.writeln(gen.formatDouble(1000 * vals[0]) + " " + + gen.formatDouble(1000 * vals[1]) + " " + + gen.formatDouble(1000 * vals[2]) + " " + + gen.formatDouble(1000 * vals[3]) + " QUADTO "); + break; + case PathIterator.SEG_CLOSE: + gen.writeln("closepath"); + break; + default: + break; + } + iter.next(); + } + doDrawing(true, false, + iter.getWindingRule() == PathIterator.WIND_EVEN_ODD); + gen.writeln("grestore"); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + /** + * Commits a painting operation. + * @param fill filling + * @param stroke stroking + * @param nonzero ??? + * @exception IOException In case of an I/O problem + */ + protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) + throws IOException { + if (fill) { + if (stroke) { + if (!nonzero) { + gen.writeln("stroke"); + } else { + gen.writeln("stroke"); + } + } else { + if (!nonzero) { + gen.writeln("fill"); + } else { + gen.writeln("fill"); + } + } + } else { + // if(stroke) + gen.writeln("stroke"); + } + } + + /** + * Returns the device configuration associated with this + * Graphics2D. + * @return the device configuration + */ + public GraphicsConfiguration getDeviceConfiguration() { + // System.out.println("getDeviceConviguration"); + return GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + } + + /** + * Used to create proper font metrics + */ + private Graphics2D fmg; + + { + BufferedImage bi = new BufferedImage(1, 1, + BufferedImage.TYPE_INT_ARGB); + + fmg = bi.createGraphics(); + } + + /** + * Sets the overrideing font state. + * @param infont FontState to set + */ + public void setOverrideFontState(FontState infont) { + overrideFontState = infont; + } + + /** + * Gets the font metrics for the specified font. + * @return the font metrics for the specified font. + * @param f the specified font + * @see java.awt.Graphics#getFont + * @see java.awt.FontMetrics + * @see java.awt.Graphics#getFontMetrics() + */ + public java.awt.FontMetrics getFontMetrics(Font f) { + return fmg.getFontMetrics(f); + } + + /** + * Sets the paint mode of this graphics context to alternate between + * this graphics context's current color and the new specified color. + * This specifies that logical pixel operations are performed in the + * XOR mode, which alternates pixels between the current color and + * a specified XOR color. + *

+ * When drawing operations are performed, pixels which are the + * current color are changed to the specified color, and vice versa. + *

+ * Pixels that are of colors other than those two colors are changed + * in an unpredictable but reversible manner; if the same figure is + * drawn twice, then all pixels are restored to their original values. + * @param c1 the XOR alternation color + */ + public void setXORMode(Color c1) { + System.out.println("setXORMode"); + } + + + /** + * Copies an area of the component by a distance specified by + * dx and dy. From the point specified + * by x and y, this method + * copies downwards and to the right. To copy an area of the + * component to the left or upwards, specify a negative value for + * dx or dy. + * If a portion of the source rectangle lies outside the bounds + * of the component, or is obscured by another window or component, + * copyArea will be unable to copy the associated + * pixels. The area that is omitted can be refreshed by calling + * the component's paint method. + * @param x the x coordinate of the source rectangle. + * @param y the y coordinate of the source rectangle. + * @param width the width of the source rectangle. + * @param height the height of the source rectangle. + * @param dx the horizontal distance to copy the pixels. + * @param dy the vertical distance to copy the pixels. + */ + public void copyArea(int x, int y, int width, int height, int dx, + int dy) { + System.out.println("copyArea"); + } + +} diff --git a/src/java/org/apache/fop/render/ps/PSProcSets.java b/src/java/org/apache/fop/render/ps/PSProcSets.java new file mode 100644 index 000000000..566328733 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSProcSets.java @@ -0,0 +1,200 @@ +/* + * $Id: PSProcSets.java,v 1.3 2003/03/11 08:42:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.IOException; + +/** + * This class defines the basic resources (procsets) used by FOP's PostScript + * renderer and SVG transcoder. + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id: PSProcSets.java,v 1.3 2003/03/11 08:42:24 jeremias Exp $ + */ +public final class PSProcSets { + + /** + * Generates a resource defining standard procset for FOP. + * @param gen PSGenerator to use for output + * @throws IOException In case of an I/O problem + */ + public static final void writeFOPStdProcSet(PSGenerator gen) throws IOException { + gen.writeln("%%BeginResource: procset (Apache FOP Std ProcSet) 1.0 0"); + gen.writeln("%%Version: 1.0 0"); + gen.writeln("%%Copyright: Copyright (C) 2001-2003 " + + "The Apache Software Foundation. All rights reserved."); + gen.writeln("%%Title: Basic set of procedures used by FOP"); + + gen.writeln("/bd{bind def}bind def"); + gen.writeln("/ld{load def}bd"); + gen.writeln("/M/moveto ld"); + gen.writeln("/RM/rmoveto ld"); + gen.writeln("/t/show ld"); + + gen.writeln("/_ctm matrix def"); //Holds the current matrix + gen.writeln("/_tm matrix def"); + //BT: save currentmatrix, set _tm to identitymatrix and move to 0/0 + gen.writeln("/BT { _ctm currentmatrix pop matrix _tm copy pop 0 0 moveto } bd"); + //ET: restore last currentmatrix + gen.writeln("/ET { _ctm setmatrix } bd"); + gen.writeln("/iTm { _ctm setmatrix _tm concat } bd"); + gen.writeln("/Tm { _tm astore pop iTm 0 0 moveto } bd"); + + gen.writeln("/ux 0.0 def"); + gen.writeln("/uy 0.0 def"); + + // F + gen.writeln("/F {"); + gen.writeln(" /Tp exch def"); + // gen.writeln(" currentdict exch get"); + gen.writeln(" /Tf exch def"); + gen.writeln(" Tf findfont Tp scalefont setfont"); + gen.writeln(" /cf Tf def /cs Tp def /cw ( ) stringwidth pop def"); + gen.writeln("} bd"); + + gen.writeln("/ULS {currentpoint /uy exch def /ux exch def} bd"); + gen.writeln("/ULE {"); + gen.writeln(" /Tcx currentpoint pop def"); + gen.writeln(" gsave"); + gen.writeln(" newpath"); + gen.writeln(" cf findfont cs scalefont dup"); + gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); + gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); + gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); + gen.writeln(" ux uy To add moveto Tcx uy To add lineto"); + gen.writeln(" Tt setlinewidth stroke"); + gen.writeln(" grestore"); + gen.writeln("} bd"); + + gen.writeln("/OLE {"); + gen.writeln(" /Tcx currentpoint pop def"); + gen.writeln(" gsave"); + gen.writeln(" newpath"); + gen.writeln(" cf findfont cs scalefont dup"); + gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); + gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); + gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); + gen.writeln(" ux uy To add cs add moveto Tcx uy To add cs add lineto"); + gen.writeln(" Tt setlinewidth stroke"); + gen.writeln(" grestore"); + gen.writeln("} bd"); + + gen.writeln("/SOE {"); + gen.writeln(" /Tcx currentpoint pop def"); + gen.writeln(" gsave"); + gen.writeln(" newpath"); + gen.writeln(" cf findfont cs scalefont dup"); + gen.writeln(" /FontMatrix get 0 get /Ts exch def /FontInfo get dup"); + gen.writeln(" /UnderlinePosition get Ts mul /To exch def"); + gen.writeln(" /UnderlineThickness get Ts mul /Tt exch def"); + gen.writeln(" ux uy To add cs 10 mul 26 idiv add moveto " + + "Tcx uy To add cs 10 mul 26 idiv add lineto"); + gen.writeln(" Tt setlinewidth stroke"); + gen.writeln(" grestore"); + gen.writeln("} bd"); + + gen.writeln("/QUADTO {"); + gen.writeln("/Y22 exch store"); + gen.writeln("/X22 exch store"); + gen.writeln("/Y21 exch store"); + gen.writeln("/X21 exch store"); + gen.writeln("currentpoint"); + gen.writeln("/Y21 load 2 mul add 3 div exch"); + gen.writeln("/X21 load 2 mul add 3 div exch"); + gen.writeln("/X21 load 2 mul /X22 load add 3 div"); + gen.writeln("/Y21 load 2 mul /Y22 load add 3 div"); + gen.writeln("/X22 load /Y22 load curveto"); + gen.writeln("} bd"); + + gen.writeln("%%EndResource"); + } + + + /** + * Generates a resource defining a procset for including EPS graphics. + * @param gen PSGenerator to use for output + * @throws IOException In case of an I/O problem + */ + public static final void writeFOPEPSProcSet(PSGenerator gen) throws IOException { + gen.writeln("%%BeginResource: procset (Apache FOP EPS ProcSet) 1.0 0"); + gen.writeln("%%Version: 1.0 0"); + gen.writeln("%%Copyright: Copyright (C) 2002-2003 " + + "The Apache Software Foundation. All rights reserved."); + gen.writeln("%%Title: EPS procedures used by FOP"); + + gen.writeln("/BeginEPSF { %def"); + gen.writeln("/b4_Inc_state save def % Save state for cleanup"); + gen.writeln("/dict_count countdictstack def % Count objects on dict stack"); + gen.writeln("/op_count count 1 sub def % Count objects on operand stack"); + gen.writeln("userdict begin % Push userdict on dict stack"); + gen.writeln("/showpage { } def % Redefine showpage, { } = null proc"); + gen.writeln("0 setgray 0 setlinecap % Prepare graphics state"); + gen.writeln("1 setlinewidth 0 setlinejoin"); + gen.writeln("10 setmiterlimit [ ] 0 setdash newpath"); + gen.writeln("/languagelevel where % If level not equal to 1 then"); + gen.writeln("{pop languagelevel % set strokeadjust and"); + gen.writeln("1 ne % overprint to their defaults."); + gen.writeln("{false setstrokeadjust false setoverprint"); + gen.writeln("} if"); + gen.writeln("} if"); + gen.writeln("} bd"); + + gen.writeln("/EndEPSF { %def"); + gen.writeln("count op_count sub {pop} repeat % Clean up stacks"); + gen.writeln("countdictstack dict_count sub {end} repeat"); + gen.writeln("b4_Inc_state restore"); + gen.writeln("} bd"); + + gen.writeln("%%EndResource"); + } + +} diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java new file mode 100644 index 000000000..9e22812ed --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -0,0 +1,901 @@ +/* + * $Id: PSRenderer.java,v 1.31 2003/03/11 08:42:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +// Java +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +// FOP +import org.apache.fop.fo.properties.BackgroundRepeat; +import org.apache.fop.area.Area; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.Block; +import org.apache.fop.area.BlockViewport; +import org.apache.fop.area.CTM; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.ForeignObject; +import org.apache.fop.area.inline.Word; +import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fonts.Font; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.render.RendererContext; + +import org.apache.fop.image.FopImage; +import org.apache.fop.image.ImageFactory; +import org.apache.fop.traits.BorderProps; + +import org.w3c.dom.Document; +/** + * Renderer that renders to PostScript. + *
+ * This class currently generates PostScript Level 2 code. The only exception + * is the FlateEncode filter which is a Level 3 feature. The filters in use + * are hardcoded at the moment. + *
+ * This class follows the Document Structuring Conventions (DSC) version 3.0. + * If anyone modifies this renderer please make + * sure to also follow the DSC to make it simpler to programmatically modify + * the generated Postscript files (ex. extract pages etc.). + *
+ * The PS renderer operates in millipoints as the layout engine. Since PostScript + * initially uses points, scaling is applied as needed. + * @todo Rebuild the PostScript renderer + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id: PSRenderer.java,v 1.31 2003/03/11 08:42:24 jeremias Exp $ + */ +public class PSRenderer extends AbstractRenderer { + + /** The MIME type for PostScript */ + public static final String MIME_TYPE = "application/postscript"; + + /** The application producing the PostScript */ + protected String producer; + private int currentPageNumber = 0; + + private boolean enableComments = true; + + /** The PostScript generator used to output the PostScript */ + protected PSGenerator gen; + private boolean ioTrouble = false; + + private String currentFontName; + private int currentFontSize; + private int pageHeight; + private int pageWidth; + private float currRed; + private float currGreen; + private float currBlue; + + private FontInfo fontInfo; + + /** + * Set the document's producer + * + * @param producer string indicating application producing the PostScript + */ + public void setProducer(String producer) { + this.producer = producer; + } + + /** + * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent) + */ + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + PSXMLHandler xmlHandler = new PSXMLHandler(); + //userAgent.setDefaultXMLHandler(MIME_TYPE, xmlHandler); + String svg = "http://www.w3.org/2000/svg"; + userAgent.addXMLHandler(MIME_TYPE, svg, xmlHandler); + } + + /** + * Write out a command + * @param cmd PostScript command + */ + protected void writeln(String cmd) { + try { + gen.writeln(cmd); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** + * Central exception handler for I/O exceptions. + * @param ioe IOException to handle + */ + protected void handleIOTrouble(IOException ioe) { + if (!ioTrouble) { + getLogger().error("Error while writing to target file", ioe); + ioTrouble = true; + } + } + + /** + * Write out a comment + * @param comment Comment to write + */ + protected void comment(String comment) { + if (this.enableComments) { + writeln(comment); + } + } + + /** + * Generates the PostScript code for the font dictionary. + * @param fontInfo available fonts + */ + protected void writeFontDict(FontInfo fontInfo) { + writeln("%%BeginResource: procset FOPFonts"); + writeln("%%Title: Font setup (shortcuts) for this file"); + writeln("/FOPFonts 100 dict dup begin"); + + // write("/gfF1{/Helvetica findfont} bd"); + // write("/gfF3{/Helvetica-Bold findfont} bd"); + Map fonts = fontInfo.getFonts(); + Iterator enum = fonts.keySet().iterator(); + while (enum.hasNext()) { + String key = (String)enum.next(); + Font fm = (Font)fonts.get(key); + writeln("/" + key + " /" + fm.getFontName() + " def"); + } + writeln("end def"); + writeln("%%EndResource"); + enum = fonts.keySet().iterator(); + while (enum.hasNext()) { + String key = (String)enum.next(); + Font fm = (Font)fonts.get(key); + writeln("/" + fm.getFontName() + " findfont"); + writeln("dup length dict begin"); + writeln(" {1 index /FID ne {def} {pop pop} ifelse} forall"); + writeln(" /Encoding ISOLatin1Encoding def"); + writeln(" currentdict"); + writeln("end"); + writeln("/" + fm.getFontName() + " exch definefont pop"); + } + } + + /** + * Make sure the cursor is in the right place. + */ + protected void movetoCurrPosition() { + moveTo(this.currentIPPosition, this.currentBPPosition); + } + + /** + * Moves the cursor. + * @param x X coordinate + * @param y Y coordinate + */ + protected void moveTo(int x, int y) { + writeln(x + " " + y + " M"); + } + + /** Saves the graphics state of the rendering engine. */ + public void saveGraphicsState() { + try { + //delegate + gen.saveGraphicsState(); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** Restores the last graphics state of the rendering engine. */ + public void restoreGraphicsState() { + try { + //delegate + gen.restoreGraphicsState(); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** Indicates the beginning of a text object. */ + protected void beginTextObject() { + writeln("BT"); + } + + /** Indicates the end of a text object. */ + protected void endTextObject() { + writeln("ET"); + } + + /** + * Concats the transformation matrix. + * @param a A part + * @param b B part + * @param c C part + * @param d D part + * @param e E part + * @param f F part + */ + protected void concatMatrix(double a, double b, + double c, double d, + double e, double f) { + try { + gen.concatMatrix(a, b, c, d, e, f); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** + * Concats the transformations matrix. + * @param matrix Matrix to use + */ + protected void concatMatrix(double[] matrix) { + try { + gen.concatMatrix(matrix); + } catch (IOException ioe) { + handleIOTrouble(ioe); + } + } + + /** + * Set up the font info + * + * @param fontInfo the font info object to set up + */ + public void setupFontInfo(FontInfo fontInfo) { + /* use PDF's font setup to get PDF metrics */ + org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); + this.fontInfo = fontInfo; + } + + /** + * Draws a filled rectangle. + * @param x x-coordinate + * @param y y-coordinate + * @param w width + * @param h height + * @param col color to fill with + */ + protected void fillRect(int x, int y, int w, int h, + ColorType col) { + useColor(col); + writeln(x + " " + y + " " + w + " " + h + " rectfill"); + } + + /** + * Draws a stroked rectangle with the current stroke settings. + * @param x x-coordinate + * @param y y-coordinate + * @param w width + * @param h height + */ + protected void drawRect(int x, int y, int w, int h) { + writeln(x + " " + y + " " + w + " " + h + " rectstroke"); + } + + /** + * Clip an area. + * Write a clipping operation given coordinates in the current + * transform. + * @param x the x coordinate + * @param y the y coordinate + * @param width the width of the area + * @param height the height of the area + */ + protected void clip(float x, float y, float width, float height) { + writeln(x + " " + y + " " + width + " " + height + " rectclip"); + } + + /** + * Changes the currently used font. + * @param name name of the font + * @param size font size + */ + public void useFont(String name, int size) { + if ((currentFontName != name) || (currentFontSize != size)) { + writeln(name + " " + size + " F"); + currentFontName = name; + currentFontSize = size; + } + } + + private void useColor(ColorType col) { + useColor(col.getRed(), col.getGreen(), col.getBlue()); + } + + private void useColor(float red, float green, float blue) { + if ((red != currRed) || (green != currGreen) || (blue != currBlue)) { + writeln(red + " " + green + " " + blue + " setrgbcolor"); + currRed = red; + currGreen = green; + currBlue = blue; + } + } + + /** + * @see org.apache.fop.render.Renderer#startRenderer(OutputStream) + */ + public void startRenderer(OutputStream outputStream) + throws IOException { + getLogger().debug("rendering areas to PostScript"); + + //Setup for PostScript generation + this.gen = new PSGenerator(outputStream); + this.currentPageNumber = 0; + + //PostScript Header + writeln(DSCConstants.PS_ADOBE_30); + gen.writeDSCComment(DSCConstants.CREATOR, new String[] {"FOP " + this.producer}); + gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new java.util.Date()}); + gen.writeDSCComment(DSCConstants.PAGES, new Object[] {PSGenerator.ATEND}); + gen.writeDSCComment(DSCConstants.END_COMMENTS); + + //Defaults + gen.writeDSCComment(DSCConstants.BEGIN_DEFAULTS); + gen.writeDSCComment(DSCConstants.END_DEFAULTS); + + //Prolog + gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); + gen.writeDSCComment(DSCConstants.END_PROLOG); + + //Setup + gen.writeDSCComment(DSCConstants.BEGIN_SETUP); + PSProcSets.writeFOPStdProcSet(gen); + PSProcSets.writeFOPEPSProcSet(gen); + writeFontDict(fontInfo); + gen.writeDSCComment(DSCConstants.END_SETUP); + } + + /** + * @see org.apache.fop.render.Renderer#stopRenderer() + */ + public void stopRenderer() throws IOException { + gen.writeDSCComment(DSCConstants.TRAILER); + gen.writeDSCComment(DSCConstants.PAGES, new Integer(this.currentPageNumber)); + gen.writeDSCComment(DSCConstants.EOF); + gen.flush(); + } + + /** + * @see org.apache.fop.render.Renderer#renderPage(PageViewport) + */ + public void renderPage(PageViewport page) + throws IOException, FOPException { + getLogger().debug("renderPage(): " + page); + + this.currentPageNumber++; + gen.writeDSCComment(DSCConstants.PAGE, new Object[] + {page.getPageNumber(), + new Integer(this.currentPageNumber)}); + final Integer zero = new Integer(0); + final Long pagewidth = new Long(Math.round(page.getViewArea().getWidth())); + final Long pageheight = new Long(Math.round(page.getViewArea().getHeight())); + gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] + {zero, zero, pagewidth, pageheight}); + gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); + gen.writeln("FOPFonts begin"); + gen.writeln("0.001 0.001 scale"); + concatMatrix(1, 0, 0, -1, 0, pageheight.doubleValue()); + + gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); + + //Process page + super.renderPage(page); + + writeln("showpage"); + gen.writeDSCComment(DSCConstants.PAGE_TRAILER); + gen.writeDSCComment(DSCConstants.END_PAGE); + } + + /** + * Paints text. + * @param rx X coordinate + * @param bl Y coordinate + * @param text Text to paint + * @param font Font to use + */ + protected void paintText(int rx, int bl, String text, Font font) { + saveGraphicsState(); + writeln("1 0 0 -1 " + rx + " " + bl + " Tm"); + + int initialSize = text.length(); + initialSize += initialSize / 2; + StringBuffer sb = new StringBuffer(initialSize); + sb.append("("); + for (int i = 0; i < text.length(); i++) { + final char c = text.charAt(i); + final char mapped = font.mapChar(c); + gen.escapeChar(mapped, sb); + } + sb.append(") t"); + writeln(sb.toString()); + restoreGraphicsState(); + } + + /** + * @see org.apache.fop.render.Renderer#renderWord(Word) + */ + public void renderWord(Word area) { + String fontname = (String)area.getTrait(Trait.FONT_NAME); + int fontsize = area.getTraitAsInteger(Trait.FONT_SIZE); + + // This assumes that *all* CIDFonts use a /ToUnicode mapping + Font f = (Font)fontInfo.getFonts().get(fontname); + + //Determine position + int rx = currentBlockIPPosition; + int bl = currentBPPosition + area.getOffset(); + + useFont(fontname, fontsize); + + paintText(rx, bl, area.getWord(), f); + +/* + String psString = null; + if (area.getFontState().getLetterSpacing() > 0) { + //float f = area.getFontState().getLetterSpacing() + // * 1000 / this.currentFontSize; + float f = area.getFontState().getLetterSpacing(); + psString = (new StringBuffer().append(f).append(" 0.0 (") + .append(sb.toString()).append(") A")).toString(); + } else { + psString = (new StringBuffer("(").append(sb.toString()) + .append(") t")).toString(); + } + + + // System.out.println("["+s+"] --> ["+sb.toString()+"]"); + + // comment("% --- InlineArea font-weight="+fontWeight+": " + sb.toString()); + useFont(fs.getFontName(), fs.getFontSize()); + useColor(area.getRed(), area.getGreen(), area.getBlue()); + if (area.getUnderlined() || area.getLineThrough() + || area.getOverlined()) + write("ULS"); + write(psString); + if (area.getUnderlined()) + write("ULE"); + if (area.getLineThrough()) + write("SOE"); + if (area.getOverlined()) + write("OLE"); + this.currentXPosition += area.getContentWidth(); + */ + super.renderWord(area); //Updates IPD + } + + + /** + * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List) + */ + protected void renderBlockViewport(BlockViewport bv, List children) { + // clip and position viewport if necessary + + // save positions + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + String saveFontName = currentFontName; + + CTM ctm = bv.getCTM(); + + if (bv.getPositioning() == Block.ABSOLUTE) { + + currentIPPosition = 0; + currentBPPosition = 0; + + //closeText(); + endTextObject(); + + if (bv.getClip()) { + saveGraphicsState(); + int x = bv.getXOffset() + containingIPPosition; + int y = bv.getYOffset() + containingBPPosition; + int width = bv.getWidth(); + int height = bv.getHeight(); + clip(x, y, width, height); + } + + CTM tempctm = new CTM(containingIPPosition, containingBPPosition); + ctm = tempctm.multiply(ctm); + + startVParea(ctm); + handleBlockTraits(bv); + renderBlocks(children); + endVParea(); + + if (bv.getClip()) { + restoreGraphicsState(); + } + beginTextObject(); + + // clip if necessary + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + } else { + + if (ctm != null) { + currentIPPosition = 0; + currentBPPosition = 0; + + //closeText(); + endTextObject(); + + double[] vals = ctm.toArray(); + //boolean aclock = vals[2] == 1.0; + if (vals[2] == 1.0) { + ctm = ctm.translate(-saveBP - bv.getHeight(), -saveIP); + } else if (vals[0] == -1.0) { + ctm = ctm.translate(-saveIP - bv.getWidth(), -saveBP - bv.getHeight()); + } else { + ctm = ctm.translate(saveBP, saveIP - bv.getWidth()); + } + } + + // clip if necessary + if (bv.getClip()) { + if (ctm == null) { + //closeText(); + endTextObject(); + } + saveGraphicsState(); + int x = bv.getXOffset(); + int y = bv.getYOffset(); + int width = bv.getWidth(); + int height = bv.getHeight(); + clip(x, y, width, height); + } + + if (ctm != null) { + startVParea(ctm); + } + handleBlockTraits(bv); + renderBlocks(children); + if (ctm != null) { + endVParea(); + } + + if (bv.getClip()) { + restoreGraphicsState(); + if (ctm == null) { + beginTextObject(); + } + } + if (ctm != null) { + beginTextObject(); + } + + currentIPPosition = saveIP; + currentBPPosition = saveBP; + currentBPPosition += (int)(bv.getHeight()); + } + currentFontName = saveFontName; + } + + /** + * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM) + */ + protected void startVParea(CTM ctm) { + // Set the given CTM in the graphics state + //currentState.push(); + //currentState.setTransform(new AffineTransform(CTMHelper.toPDFArray(ctm))); + + saveGraphicsState(); + // multiply with current CTM + //writeln(CTMHelper.toPDFString(ctm) + " cm\n"); + final double matrix[] = ctm.toArray(); + concatMatrix(matrix); + + // Set clip? + beginTextObject(); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#endVParea() + */ + protected void endVParea() { + endTextObject(); + restoreGraphicsState(); + //currentState.pop(); + } + + /** + * Handle the viewport traits. + * This is used to draw the traits for a viewport. + * + * @param region the viewport region to handle + */ + protected void handleViewportTraits(RegionViewport region) { + currentFontName = ""; + float startx = 0; + float starty = 0; + Rectangle2D viewArea = region.getViewArea(); + float width = (float)(viewArea.getWidth()); + float height = (float)(viewArea.getHeight()); + /* + Trait.Background back; + back = (Trait.Background)region.getTrait(Trait.BACKGROUND); + */ + drawBackAndBorders(region, startx, starty, width, height); + } + + /** + * Handle block traits. + * The block could be any sort of block with any positioning + * so this should render the traits such as border and background + * in its position. + * + * @param block the block to render the traits + */ + protected void handleBlockTraits(Block block) { + float startx = currentIPPosition; + float starty = currentBPPosition; + drawBackAndBorders(block, startx, starty, + block.getWidth(), block.getHeight()); + } + + /** + * Draw the background and borders. + * This draws the background and border traits for an area given + * the position. + * + * @param block the area to get the traits from + * @param startx the start x position + * @param starty the start y position + * @param width the width of the area + * @param height the height of the area + */ + protected void drawBackAndBorders(Area block, + float startx, float starty, + float width, float height) { + // draw background then border + + boolean started = false; + Trait.Background back; + back = (Trait.Background)block.getTrait(Trait.BACKGROUND); + if (back != null) { + started = true; +// closeText(); + endTextObject(); + //saveGraphicsState(); + + if (back.getColor() != null) { + updateColor(back.getColor(), true, null); + writeln(startx + " " + starty + " " + + width + " " + height + " rectfill"); + } + if (back.getURL() != null) { + ImageFactory fact = ImageFactory.getInstance(); + FopImage fopimage = fact.getImage(back.getURL(), userAgent); + if (fopimage != null && fopimage.load(FopImage.DIMENSIONS, userAgent)) { + if (back.getRepeat() == BackgroundRepeat.REPEAT) { + // create a pattern for the image + } else { + // place once + Rectangle2D pos; + pos = new Rectangle2D.Float((startx + back.getHoriz()) * 1000, + (starty + back.getVertical()) * 1000, + fopimage.getWidth() * 1000, + fopimage.getHeight() * 1000); + // putImage(back.url, pos); + } + } + } + } + + BorderProps bps = (BorderProps)block.getTrait(Trait.BORDER_BEFORE); + if (bps != null) { + float endx = startx + width; + + if (!started) { + started = true; +// closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width ; + updateColor(bps.color, false, null); + writeln(bwidth + " setlinewidth"); + + drawLine(startx, starty + bwidth / 2, endx, starty + bwidth / 2); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_START); + if (bps != null) { + float endy = starty + height; + + if (!started) { + started = true; +// closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width ; + updateColor(bps.color, false, null); + writeln(bwidth + " setlinewidth"); + + drawLine(startx + bwidth / 2, starty, startx + bwidth / 2, endy); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_AFTER); + if (bps != null) { + float sy = starty + height; + float endx = startx + width; + + if (!started) { + started = true; +// closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width ; + updateColor(bps.color, false, null); + writeln(bwidth + " setlinewidth"); + + drawLine(startx, sy - bwidth / 2, endx, sy - bwidth / 2); + } + bps = (BorderProps)block.getTrait(Trait.BORDER_END); + if (bps != null) { + float sx = startx + width; + float endy = starty + height; + + if (!started) { + started = true; + // closeText(); + endTextObject(); + //saveGraphicsState(); + } + + float bwidth = bps.width ; + updateColor(bps.color, false, null); + writeln(bwidth + " setlinewidth"); + drawLine(sx - bwidth / 2, starty, sx - bwidth / 2, endy); + } + if (started) { + //restoreGraphicsState(); + beginTextObject(); + // font last set out of scope in text section + currentFontName = ""; + } + } + + /** + * Draw a line. + * + * @param startx the start x position + * @param starty the start y position + * @param endx the x end position + * @param endy the y end position + */ + private void drawLine(float startx, float starty, float endx, float endy) { + writeln(startx + " " + starty + " M "); + writeln(endx + " " + endy + " lineto"); + } + + private void updateColor(ColorType col, boolean fill, StringBuffer pdf) { + writeln(gen.formatDouble(col.getRed()) + " " + + gen.formatDouble(col.getGreen()) + " " + + gen.formatDouble(col.getBlue()) + " setrgbcolor"); + } + + private void updateFont(String name, int size, StringBuffer pdf) { + + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderForeignObject(ForeignObject, Rectangle2D) + */ + public void renderForeignObject(ForeignObject fo, Rectangle2D pos) { + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + renderDocument(doc, ns, pos); + } + + /** + * Renders an XML document (SVG for example). + * @param doc DOM Document containing the XML document to be rendered + * @param ns Namespace for the XML document + * @param pos Position for the generated graphic/image + */ + public void renderDocument(Document doc, String ns, Rectangle2D pos) { + RendererContext context; + context = new RendererContext(MIME_TYPE); + context.setUserAgent(userAgent); + + context.setProperty(PSXMLHandler.PS_GENERATOR, this.gen); + context.setProperty(PSXMLHandler.PS_FONT_INFO, fontInfo); + context.setProperty(PSXMLHandler.PS_WIDTH, + new Integer((int) pos.getWidth())); + context.setProperty(PSXMLHandler.PS_HEIGHT, + new Integer((int) pos.getHeight())); + context.setProperty(PSXMLHandler.PS_XPOS, + new Integer(currentBlockIPPosition + (int) pos.getX())); + context.setProperty(PSXMLHandler.PS_YPOS, + new Integer(currentBPPosition + (int) pos.getY())); + //context.setProperty("strokeSVGText", options.get("strokeSVGText")); + + /* + context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); + context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream); + context.setProperty(PDFXMLHandler.PDF_STATE, currentState); + context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage); + context.setProperty(PDFXMLHandler.PDF_CONTEXT, + currentContext == null ? currentPage: currentContext); + context.setProperty(PDFXMLHandler.PDF_CONTEXT, currentContext); + context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream); + context.setProperty(PDFXMLHandler.PDF_XPOS, + new Integer(currentBlockIPPosition + (int) pos.getX())); + context.setProperty(PDFXMLHandler.PDF_YPOS, + new Integer(currentBPPosition + (int) pos.getY())); + context.setProperty(PDFXMLHandler.PDF_FONT_INFO, fontInfo); + context.setProperty(PDFXMLHandler.PDF_FONT_NAME, currentFontName); + context.setProperty(PDFXMLHandler.PDF_FONT_SIZE, + new Integer(currentFontSize)); + context.setProperty(PDFXMLHandler.PDF_WIDTH, + new Integer((int) pos.getWidth())); + context.setProperty(PDFXMLHandler.PDF_HEIGHT, + new Integer((int) pos.getHeight())); + */ + userAgent.renderXML(context, doc, ns); + + } + + + + +} diff --git a/src/java/org/apache/fop/render/ps/PSState.java b/src/java/org/apache/fop/render/ps/PSState.java new file mode 100644 index 000000000..32daaee53 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSState.java @@ -0,0 +1,97 @@ +/* + * $Id: PSState.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.Serializable; +import java.awt.geom.AffineTransform; + +/** + * This class holds the current state of the PostScript interpreter. + * + * @author Apache XML FOP Development Team + * @author Jeremias Maerki + * @version $Id: PSState.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + */ +public class PSState implements Serializable, Cloneable { + + private AffineTransform transform = new AffineTransform(); + + + + /** + * Returns the transform. + * @return the current transformation matrix + */ + public AffineTransform getTransform() { + return this.transform; + } + + /** + * Concats the given transformation matrix with the current one. + * @param transform The new transformation matrix + */ + public void concatMatrix(AffineTransform transform) { + this.transform.concatenate(transform); + } + + /** + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + +} diff --git a/src/java/org/apache/fop/render/ps/PSTextElementBridge.java b/src/java/org/apache/fop/render/ps/PSTextElementBridge.java new file mode 100644 index 000000000..e7bc31fe8 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSTextElementBridge.java @@ -0,0 +1,159 @@ +/* + * $Id: PSTextElementBridge.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +//import org.apache.batik.gvt.TextNode; +import org.apache.batik.bridge.SVGTextElementBridge; +import org.apache.batik.bridge.BridgeContext; +//import org.apache.batik.bridge.TextUtilities; +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.fop.layout.FontInfo; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Bridge class for the <text> element. + * This bridge will use the direct text painter if the text + * for the element is simple. + * + * @author Apache XML FOP Development Team + * @version $Id: PSTextElementBridge.java,v 1.2 2003/03/07 09:46:30 jeremias Exp $ + */ +public class PSTextElementBridge extends SVGTextElementBridge { + + //private PSTextPainter textPainter; + + /** + * Constructs a new bridge for the <text> element. + * @param fi the font infomration + */ + public PSTextElementBridge(FontInfo fi) { + //textPainter = new PSTextPainter(fi); + } + + /** + * Create a text element bridge. + * This set the text painter on the node if the text is simple. + * @param ctx the bridge context + * @param e the svg element + * @return the text graphics node created by the super class + */ + public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { + GraphicsNode node = super.createGraphicsNode(ctx, e); + /* + if (node != null && isSimple(ctx, e, node)) { + ((TextNode)node).setTextPainter(getTextPainter()); + }*/ + return node; + } + + /* + private PSTextPainter getTextPainter() { + return textPainter; + } + */ + + /** + * Check if text element contains simple text. + * This checks the children of the text element to determine + * if the text is simple. The text is simple if it can be rendered + * with basic text drawing algorithms. This means there are no + * alternate characters, the font is known and there are no effects + * applied to the text. + * + * @param ctx the bridge context + * @param element the svg text element + * @param node the graphics node + * @return true if this text is simple of false if it cannot be + * easily rendered using normal drawString on the PDFGraphics2D + */ + private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) { + /* + // Font size, in user space units. + float fs = TextUtilities.convertFontSize(element).floatValue(); + // PDF cannot display fonts over 36pt + if (fs > 36) { + return false; + } + */ + + + for (Node n = element.getFirstChild(); + n != null; + n = n.getNextSibling()) { + + switch (n.getNodeType()) { + case Node.ELEMENT_NODE: + + if (n.getLocalName().equals(SVG_TSPAN_TAG) + || n.getLocalName().equals(SVG_ALT_GLYPH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TEXT_PATH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TREF_TAG)) { + return false; + } + break; + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + } + } + + /*if (CSSUtilities.convertFilter(element, node, ctx) != null) { + return false; + }*/ + + return true; + } +} + diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java new file mode 100644 index 000000000..6f2aab65a --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -0,0 +1,435 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.awt.Graphics2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.Font; + +import java.text.AttributedCharacterIterator; +import java.awt.font.TextAttribute; +import java.awt.Shape; +import java.awt.Paint; +import java.awt.Stroke; +import java.awt.Color; +import java.util.List; +import java.util.Iterator; + +import org.apache.batik.gvt.text.Mark; +import org.apache.batik.gvt.TextPainter; +import org.apache.batik.gvt.TextNode; +import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; +import org.apache.batik.gvt.font.GVTFontFamily; +import org.apache.batik.bridge.SVGFontFamily; +import org.apache.batik.gvt.renderer.StrokingTextPainter; + +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.FontInfo; + +/** + * Renders the attributed character iterator of a TextNode. + * This class draws the text directly into the PSGraphics2D so that + * the text is not drawn using shapes which makes the PS files larger. + * If the text is simple enough to draw then it sets the font and calls + * drawString. If the text is complex or the cannot be translated + * into a simple drawString the StrokingTextPainter is used instead. + * + * @todo handle underline, overline and strikethrough + * @todo use drawString(AttributedCharacterIterator iterator...) for some + * + * @author Keiron Liddle + * @version $Id: PSTextPainter.java,v 1.15 2003/01/08 14:03:55 jeremias Exp $ + */ +public class PSTextPainter implements TextPainter { + private FontInfo fontInfo; + + /** + * 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(); + + /** + * Create a new PS text painter with the given font information. + * @param fi the fint info + */ + public PSTextPainter(FontInfo fi) { + fontInfo = fi; + } + + /** + * Paints the specified attributed character iterator using the + * specified Graphics2D and context and font context. + * @param node the TextNode to paint + * @param g2d the Graphics2D to use + */ + public void paint(TextNode node, Graphics2D g2d) { + // System.out.println("PSText paint"); + String txt = node.getText(); + Point2D loc = node.getLocation(); + + AttributedCharacterIterator aci = + node.getAttributedCharacterIterator(); + // reset position to start of char iterator + if (aci.getBeginIndex() == aci.getEndIndex()) { + return; + } + char ch = aci.first(); + if (ch == AttributedCharacterIterator.DONE) { + return; + } + TextNode.Anchor anchor; + anchor = (TextNode.Anchor) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); + + List gvtFonts; + gvtFonts = (List) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); + Paint forg = (Paint) aci.getAttribute(TextAttribute.FOREGROUND); + Paint strokePaint; + strokePaint = (Paint) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT); + Float size = (Float) aci.getAttribute(TextAttribute.SIZE); + if (size == null) { + return; + } + Stroke stroke = (Stroke) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.STROKE); + /* + Float xpos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.X); + Float ypos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.Y); + */ + + Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE); + Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT); + + boolean useStrokePainter = false; + + if (forg instanceof Color) { + Color col = (Color) forg; + if (col.getAlpha() != 255) { + useStrokePainter = true; + } + g2d.setColor(col); + } + g2d.setPaint(forg); + g2d.setStroke(stroke); + + if (strokePaint != null) { + // need to draw using AttributedCharacterIterator + useStrokePainter = true; + } + + if (hasUnsupportedAttributes(aci)) { + useStrokePainter = true; + } + + // text contains unsupported information + if (useStrokePainter) { + PROXY_PAINTER.paint(node, g2d); + return; + } + + String style = ((posture != null) && (posture.floatValue() > 0.0)) + ? "italic" : "normal"; + int weight = ((taWeight != null) + && (taWeight.floatValue() > 1.0)) ? FontInfo.BOLD + : FontInfo.NORMAL; + + FontState fontState = null; + FontInfo fi = fontInfo; + boolean found = false; + String fontFamily = null; + if (gvtFonts != null) { + Iterator i = gvtFonts.iterator(); + while (i.hasNext()) { + GVTFontFamily fam = (GVTFontFamily) i.next(); + if (fam instanceof SVGFontFamily) { + PROXY_PAINTER.paint(node, g2d); + return; + } + fontFamily = fam.getFamilyName(); + if (fi.hasFont(fontFamily, style, weight)) { + String fname = fontInfo.fontLookup(fontFamily, style, + weight); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + int fsize = (int)(size.floatValue() * 1000); + fontState = new FontState(fname, metrics, fsize); + found = true; + break; + } + } + } + if (!found) { + String fname = + fontInfo.fontLookup("any", style, FontInfo.NORMAL); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + int fsize = (int)(size.floatValue() * 1000); + fontState = new FontState(fname, metrics, fsize); + } else { + if (g2d instanceof PSGraphics2D) { + ((PSGraphics2D) g2d).setOverrideFontState(fontState); + } + } + int fStyle = Font.PLAIN; + if (weight == FontInfo.BOLD) { + if (style.equals("italic")) { + fStyle = Font.BOLD | Font.ITALIC; + } else { + fStyle = Font.BOLD; + } + } else { + if (style.equals("italic")) { + fStyle = Font.ITALIC; + } else { + fStyle = Font.PLAIN; + } + } + Font font = new Font(fontFamily, fStyle, + (int)(fontState.getFontSize() / 1000)); + + g2d.setFont(font); + + float advance = getStringWidth(txt, fontState); + 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; + } + } + g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); + } + + private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) { + boolean hasunsupported = false; + Object letSpace = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING); + if (letSpace != null) { + hasunsupported = true; + } + + Object wordSpace = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING); + if (wordSpace != null) { + hasunsupported = true; + } + + AttributedCharacterIterator.Attribute key; + key = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE; + Object writeMod = aci.getAttribute(key); + if (!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals( + writeMod)) { + hasunsupported = true; + } + + Object vertOr = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION); + if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals( + vertOr)) { + hasunsupported = true; + } + return hasunsupported; + } + + private float getStringWidth(String str, FontState fontState) { + float wordWidth = 0; + float whitespaceWidth = fontState.getWidth(fontState.mapChar(' ')); + + for (int i = 0; i < str.length(); i++) { + float charWidth; + char c = str.charAt(i); + if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) { + charWidth = fontState.getWidth(fontState.mapChar(c)); + if (charWidth <= 0) { + charWidth = whitespaceWidth; + } + } else { + charWidth = whitespaceWidth; + } + wordWidth += charWidth; + } + return wordWidth / 1000f; + } + + /** + * Get the outline shape of the text characters. + * This uses the StrokingTextPainter to get the outline + * shape since in theory it should be the same. + * + * @param node the text node + * @return the outline shape of the text characters + */ + public Shape getOutline(TextNode node) { + return PROXY_PAINTER.getOutline(node); + } + + /** + * Get the bounds. + * This uses the StrokingTextPainter to get the bounds + * since in theory it should be the same. + * + * @param node the text node + * @return the bounds of the text + */ + public Rectangle2D getBounds2D(TextNode node) { + return PROXY_PAINTER.getBounds2D(node); + } + + /** + * Get the geometry bounds. + * This uses the StrokingTextPainter to get the bounds + * since in theory it should be the same. + * @param node the text node + * @return the bounds of the text + */ + public Rectangle2D getGeometryBounds(TextNode node) { + return PROXY_PAINTER.getGeometryBounds(node); + } + + // Methods that have no purpose for PS + + /** + * Get the mark. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @param pos the position + * @param all select all + * @return null + */ + public Mark getMark(TextNode node, int pos, boolean all) { + System.out.println("PSText getMark"); + return null; + } + + /** + * Select at. + * This does nothing since the output is pdf and not interactive. + * @param x the x position + * @param y the y position + * @param node the text node + * @return null + */ + public Mark selectAt(double x, double y, TextNode node) { + System.out.println("PSText selectAt"); + return null; + } + + /** + * Select to. + * This does nothing since the output is pdf and not interactive. + * @param x the x position + * @param y the y position + * @param beginMark the start mark + * @return null + */ + public Mark selectTo(double x, double y, Mark beginMark) { + System.out.println("PSText selectTo"); + return null; + } + + /** + * Selec first. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @return null + */ + public Mark selectFirst(TextNode node) { + System.out.println("PSText selectFirst"); + return null; + } + + /** + * Select last. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @return null + */ + public Mark selectLast(TextNode node) { + System.out.println("PSText selectLast"); + return null; + } + + /** + * Get selected. + * This does nothing since the output is pdf and not interactive. + * @param start the start mark + * @param finish the finish mark + * @return null + */ + public int[] getSelected(Mark start, Mark finish) { + System.out.println("PSText getSelected"); + return null; + } + + /** + * Get the highlighted shape. + * This does nothing since the output is pdf and not interactive. + * @param beginMark the start mark + * @param endMark the end mark + * @return null + */ + public Shape getHighlightShape(Mark beginMark, Mark endMark) { + System.out.println("PSText getHighlightShape"); + return null; + } + +} + + diff --git a/src/java/org/apache/fop/render/ps/PSXMLHandler.java b/src/java/org/apache/fop/render/ps/PSXMLHandler.java new file mode 100644 index 000000000..3b4ddcdd1 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/PSXMLHandler.java @@ -0,0 +1,379 @@ +/* + * $Id: PSXMLHandler.java,v 1.4 2003/03/11 08:42:24 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +// Java +import java.awt.geom.AffineTransform; +import java.io.IOException; + +// DOM +import org.w3c.dom.Document; +import org.w3c.dom.svg.SVGDocument; +import org.w3c.dom.svg.SVGSVGElement; + +// Batik +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.ViewBox; +import org.apache.batik.gvt.GraphicsNode; +import org.apache.batik.gvt.TextPainter; + +// FOP +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; +import org.apache.fop.svg.SVGUserAgent; +import org.apache.fop.layout.FontInfo; + +/** + * PostScript XML handler. + * This handler handles XML for foreign objects when rendering to PostScript. + * It renders SVG to the PostScript document using the PSGraphics2D. + * The properties from the PostScript renderer are subject to change. + * + * @author Apache XML FOP Development Team + * @version $Id: PSXMLHandler.java,v 1.4 2003/03/11 08:42:24 jeremias Exp $ + */ +public class PSXMLHandler implements XMLHandler { + + /** + * The PostScript generator that is being used to drawn into. + */ + public static final String PS_GENERATOR = "psGenerator"; + + /** + * The font information for the PostScript renderer. + */ + public static final String PS_FONT_INFO = "psFontInfo"; + + /** + * The width of the SVG graphic. + */ + public static final String PS_WIDTH = "width"; + + /** + * The height of the SVG graphic. + */ + public static final String PS_HEIGHT = "height"; + + /** + * The x position that this is being drawn at. + */ + public static final String PS_XPOS = "xpos"; + + /** + * The y position that this is being drawn at. + */ + public static final String PS_YPOS = "ypos"; + + /** + * Create a new PostScript XML handler for use by the PostScript renderer. + */ + public PSXMLHandler() { + } + + /** + * Handle the XML. + * This checks the type of XML and handles appropraitely. + * + * @param context the renderer context + * @param doc the XML document to render + * @param ns the namespace of the XML document + * @throws Exception any sort of exception could be thrown and shuld be handled + */ + public void handleXML(RendererContext context, Document doc, + String ns) throws Exception { + PSInfo psi = getPSInfo(context); + + String svg = "http://www.w3.org/2000/svg"; + if (svg.equals(ns)) { + SVGHandler svghandler = new SVGHandler(); + svghandler.renderSVGDocument(context, doc, psi); + } else { + } + } + + /** + * Get the pdf information from the render context. + * + * @param context the renderer context + * @return the pdf information retrieved from the context + */ + public static PSInfo getPSInfo(RendererContext context) { + PSInfo psi = new PSInfo(); + psi.psGenerator = (PSGenerator)context.getProperty(PS_GENERATOR); + psi.fontInfo = (FontInfo)context.getProperty(PS_FONT_INFO); + psi.width = ((Integer)context.getProperty(PS_WIDTH)).intValue(); + psi.height = ((Integer)context.getProperty(PS_HEIGHT)).intValue(); + psi.currentXPosition = ((Integer)context.getProperty(PS_XPOS)).intValue(); + psi.currentYPosition = ((Integer)context.getProperty(PS_YPOS)).intValue(); + return psi; + } + + /** + * PostScript information structure for drawing the XML document. + */ + public static class PSInfo { + + /** see PS_GENERATOR */ + private PSGenerator psGenerator; + /** see PS_FONT_INFO */ + private FontInfo fontInfo; + /** see PS_PAGE_WIDTH */ + private int width; + /** see PS_PAGE_HEIGHT */ + private int height; + /** see PS_XPOS */ + private int currentXPosition; + /** see PS_YPOS */ + private int currentYPosition; + /** + * Returns the PSGenerator. + * @return PSGenerator + */ + public PSGenerator getPSGenerator() { + return psGenerator; + } + + /** + * Sets the PSGenerator. + * @param psGenerator The PSGenerator to set + */ + public void setPsGenerator(PSGenerator psGenerator) { + this.psGenerator = psGenerator; + } + + /** + * Returns the fontInfo. + * @return FontInfo + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + /** + * Sets the fontInfo. + * @param fontInfo The fontInfo to set + */ + public void setFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + /** + * Returns the currentXPosition. + * @return int + */ + public int getCurrentXPosition() { + return currentXPosition; + } + + /** + * Sets the currentXPosition. + * @param currentXPosition The currentXPosition to set + */ + public void setCurrentXPosition(int currentXPosition) { + this.currentXPosition = currentXPosition; + } + + /** + * Returns the currentYPosition. + * @return int + */ + public int getCurrentYPosition() { + return currentYPosition; + } + + /** + * Sets the currentYPosition. + * @param currentYPosition The currentYPosition to set + */ + public void setCurrentYPosition(int currentYPosition) { + this.currentYPosition = currentYPosition; + } + + /** + * Returns the width. + * @return int + */ + public int getWidth() { + return width; + } + + /** + * Sets the width. + * @param width The pageWidth to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * Returns the height. + * @return int + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * @param height The height to set + */ + public void setHeight(int height) { + this.height = height; + } + + } + + /** + * This method is placed in an inner class so that we don't get class + * loading errors if batik is not present. + */ + protected class SVGHandler { + /** + * Render the svg document. + * @param context the renderer context + * @param doc the svg document + * @param psInfo the pdf information of the current context + */ + protected void renderSVGDocument(RendererContext context, Document doc, PSInfo psInfo) { + int xOffset = psInfo.currentXPosition; + int yOffset = psInfo.currentYPosition; + PSGenerator gen = psInfo.psGenerator; + + SVGUserAgent ua + = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); + + + GVTBuilder builder = new GVTBuilder(); + BridgeContext ctx = new BridgeContext(ua); + PSTextElementBridge tBridge = new PSTextElementBridge(psInfo.getFontInfo()); + ctx.putBridge(tBridge); + + //PSAElementBridge aBridge = new PSAElementBridge(); + // to get the correct transform we need to use the PDFState + AffineTransform transform = gen.getCurrentState().getTransform(); + transform.translate(xOffset / 1000f, yOffset / 1000f); + //aBridge.setCurrentTransform(transform); + //ctx.putBridge(aBridge); + + TextPainter textPainter = new PSTextPainter(psInfo.getFontInfo()); + ctx.setTextPainter(textPainter); + GraphicsNode root; + try { + root = builder.build(ctx, doc); + } catch (Exception e) { + context.getUserAgent().getLogger().error("SVG graphic could not be built: " + + e.getMessage(), e); + return; + } + // get the 'width' and 'height' attributes of the SVG document + float w = (float)ctx.getDocumentSize().getWidth() * 1000f; + float h = (float)ctx.getDocumentSize().getHeight() * 1000f; + + float sx = psInfo.getWidth() / (float)w; + float sy = psInfo.getHeight() / (float)h; + + ctx = null; + builder = null; + + try { + gen.writeln("%SVG graphic start ---"); + /* + * Clip to the svg area. + * Note: To have the svg overlay (under) a text area then use + * an fo:block-container + */ + gen.saveGraphicsState(); + // transform so that the coordinates (0,0) is from the top left + // and positive is down and to the right. (0,0) is where the + // viewBox puts it. + gen.concatMatrix(sx, 0, 0, sy, xOffset, yOffset); + + SVGSVGElement svg = ((SVGDocument)doc).getRootElement(); + AffineTransform at = ViewBox.getPreserveAspectRatioTransform(svg, + w / 1000f, h / 1000f); + if (!at.isIdentity()) { + double[] vals = new double[6]; + at.getMatrix(vals); + gen.concatMatrix(vals); + } + + /* + if (psInfo.pdfContext == null) { + psInfo.pdfContext = psInfo.pdfPage; + }*/ + PSGraphics2D graphics = new PSGraphics2D(true, gen); + graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); + //psInfo.pdfState.push(); + transform = new AffineTransform(); + // scale to viewbox + transform.translate(xOffset, yOffset); + gen.getCurrentState().concatMatrix(transform); + //graphics.setPDFState(psInfo.pdfState); + try { + root.paint(graphics); + //psInfo.currentStream.add(graphics.getString()); + } catch (Exception e) { + context.getUserAgent().getLogger().error("SVG graphic could not be rendered: " + + e.getMessage(), e); + } + + psInfo.psGenerator.restoreGraphicsState(); + //psInfo.pdfState.pop(); + gen.writeln("%SVG graphic end ---"); + } catch (IOException ioe) { + context.getUserAgent().getLogger().error("SVG graphic could not be rendered: " + + ioe.getMessage(), ioe); + } + } + } +} + diff --git a/src/java/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java b/src/java/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java new file mode 100644 index 000000000..bdad9c0f0 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/RunLengthEncodeOutputStream.java @@ -0,0 +1,217 @@ +/* + * $Id: RunLengthEncodeOutputStream.java,v 1.3 2003/03/07 09:46:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.ps; + +import java.io.FilterOutputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * This class applies a RunLengthEncode filter to the stream. + * + * @author Stephen Wolke + * @version $Id: RunLengthEncodeOutputStream.java,v 1.3 2003/03/07 09:46:30 jeremias Exp $ + */ +public class RunLengthEncodeOutputStream extends FilterOutputStream + implements Finalizable { + + private static final int MAX_SEQUENCE_COUNT = 127; + private static final int END_OF_DATA = 128; + private static final int BYTE_MAX = 256; + + private static final int NOT_IDENTIFY_SEQUENCE = 0; + private static final int START_SEQUENCE = 1; + private static final int IN_SEQUENCE = 2; + private static final int NOT_IN_SEQUENCE = 3; + + private int runCount = 0; + private int isSequence = NOT_IDENTIFY_SEQUENCE; + private byte[] runBuffer = new byte[MAX_SEQUENCE_COUNT + 1]; + + + /** @see java.io.FilterOutputStream **/ + public RunLengthEncodeOutputStream(OutputStream out) { + super(out); + } + + + /** @see java.io.FilterOutputStream **/ + public void write(byte b) + throws java.io.IOException { + runBuffer[runCount] = b; + + switch (runCount) { + case 0: + runCount = 0; + isSequence = NOT_IDENTIFY_SEQUENCE; + runCount++; + break; + case 1: + if (runBuffer[runCount] != runBuffer[runCount - 1]) { + isSequence = NOT_IN_SEQUENCE; + } + runCount++; + break; + case 2: + if (runBuffer[runCount] != runBuffer[runCount - 1]) { + isSequence = NOT_IN_SEQUENCE; + } else { + if (isSequence == NOT_IN_SEQUENCE) { + isSequence = START_SEQUENCE; + } else { + isSequence = IN_SEQUENCE; + } + } + runCount++; + break; + case MAX_SEQUENCE_COUNT: + if (isSequence == IN_SEQUENCE) { + out.write(BYTE_MAX - (MAX_SEQUENCE_COUNT - 1)); + out.write(runBuffer[runCount - 1]); + runBuffer[0] = runBuffer[runCount]; + runCount = 1; + } else { + out.write(MAX_SEQUENCE_COUNT); + out.write(runBuffer, 0, runCount + 1); + runCount = 0; + } + isSequence = NOT_IDENTIFY_SEQUENCE; + break; + default: + switch (isSequence) { + case IN_SEQUENCE: + if (runBuffer[runCount] != runBuffer[runCount - 1]) { + out.write(BYTE_MAX - (runCount - 1)); + out.write(runBuffer[runCount - 1]); + runBuffer[0] = runBuffer[runCount]; + runCount = 1; + isSequence = NOT_IDENTIFY_SEQUENCE; + break; + } + runCount++; + break; + case NOT_IN_SEQUENCE: + if (runBuffer[runCount] == runBuffer[runCount - 1]) { + isSequence = START_SEQUENCE; + } + runCount++; + break; + case START_SEQUENCE: + if (runBuffer[runCount] == runBuffer[runCount - 1]) { + out.write(runCount - 3); + out.write(runBuffer, 0, runCount - 2); + runBuffer[0] = runBuffer[runCount]; + runBuffer[1] = runBuffer[runCount]; + runBuffer[2] = runBuffer[runCount]; + runCount = 3; + isSequence = IN_SEQUENCE; + break; + } else { + isSequence = NOT_IN_SEQUENCE; + runCount++; + break; + } + } + } + } + + + /** @see java.io.FilterOutputStream **/ + public void write(byte[] b) + throws IOException { + + for (int i = 0; i < b.length; i++) { + this.write(b[i]); + } + } + + + /** @see java.io.FilterOutputStream **/ + public void write(byte[] b, int off, int len) + throws IOException { + + for (int i = 0; i < len; i++) { + this.write(b[off + i]); + } + } + + + /** @see org.apache.fop.render.ps.Finalizable **/ + public void finalizeStream() + throws IOException { + switch (isSequence) { + case IN_SEQUENCE: + out.write(BYTE_MAX - (runCount - 1)); + out.write(runBuffer[runCount - 1]); + break; + default: + out.write(runCount - 1); + out.write(runBuffer, 0, runCount); + } + + out.write(END_OF_DATA); + + flush(); + if (out instanceof Finalizable) { + ((Finalizable) out).finalizeStream(); + } + } + + + /** @see java.io.FilterOutputStream **/ + public void close() + throws IOException { + finalizeStream(); + super.close(); + } + +} + diff --git a/src/java/org/apache/fop/render/svg/SVGRenderer.java b/src/java/org/apache/fop/render/svg/SVGRenderer.java new file mode 100644 index 000000000..598a6b0ee --- /dev/null +++ b/src/java/org/apache/fop/render/svg/SVGRenderer.java @@ -0,0 +1,457 @@ +/* + * $Id: SVGRenderer.java,v 1.10 2003/03/07 09:46:33 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.svg; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.Title; +import org.apache.fop.area.inline.ForeignObject; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Word; +import org.apache.fop.svg.SVGUtilities; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fo.properties.RuleStyle; + +import org.w3c.dom.Node; +import org.w3c.dom.svg.SVGSVGElement; +import org.w3c.dom.svg.SVGDocument; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Text; + +import org.apache.batik.dom.svg.SVGDOMImplementation; +import org.apache.batik.dom.util.XMLSupport; +import org.apache.batik.transcoder.svg2svg.SVGTranscoder; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.dom.util.DOMUtilities; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; +import java.io.OutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; + +import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; + +/** + * This is the SVG renderer. + */ +public class SVGRenderer extends AbstractRenderer implements XMLHandler { + + /** SVG MIME type */ + public static final String SVG_MIME_TYPE = "image/svg+xml"; + + /** SVG namespace */ + public static final String SVG_NAMESPACE = SVGDOMImplementation.SVG_NAMESPACE_URI; + + private Document svgDocument; + private Element svgRoot; + private Element currentPageG = null; + private Element lastLink = null; + private String lastViewbox = null; + + private Element docDefs = null; + private Element pageDefs = null; + private Element pagesGroup = null; + + // first sequence title + private Title docTitle = null; + + private RendererContext context; + + private OutputStream ostream; + + private float totalWidth = 0; + private float totalHeight = 0; + private float sequenceWidth = 0; + private float sequenceHeight = 0; + + private float pageWidth = 0; + private float pageHeight = 0; + private int pageNumber = 0; + + private HashMap fontNames = new HashMap(); + private HashMap fontStyles = new HashMap(); + private Color saveColor = null; + + /** + * The current (internal) font name + */ + private String currentFontName; + + /** + * The current font size in millipoints + */ + private int currentFontSize; + + /** + * The current colour's red, green and blue component + */ + private float currentRed = 0; + private float currentGreen = 0; + private float currentBlue = 0; + + /** + * Creates a new SVG renderer. + */ + public SVGRenderer() { + context = new RendererContext(SVG_MIME_TYPE); + } + + /** + * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent) + */ + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + userAgent.setDefaultXMLHandler(SVG_MIME_TYPE, this); + userAgent.addXMLHandler(SVG_MIME_TYPE, SVG_NAMESPACE, this); + } + + /** + * @see org.apache.fop.render.Renderer#setupFontInfo(FontInfo) + */ + public void setupFontInfo(FontInfo fontInfo) { + // create a temp Image to test font metrics on + BufferedImage fontImage = + new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + org.apache.fop.render.awt.FontSetup.setup(fontInfo, + fontImage.createGraphics()); + } + + /** + * @see org.apache.fop.render.Renderer#setProducer(String) + */ + public void setProducer(String producer) { + } + + /** + * @see org.apache.fop.render.Renderer#startRenderer(OutputStream) + */ + public void startRenderer(OutputStream outputStream) + throws IOException { + ostream = outputStream; + DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); + svgDocument = impl.createDocument(SVG_NAMESPACE, "svg", null); + svgRoot = svgDocument.getDocumentElement(); + /* + ProcessingInstruction pi = + svgDocument.createProcessingInstruction("xml", + " version=\"1.0\" encoding=\"ISO-8859-1\""); + svgDocument.insertBefore(pi, svgRoot); + */ + + docDefs = svgDocument.createElementNS(SVG_NAMESPACE, "defs"); + svgRoot.appendChild(docDefs); + + pagesGroup = svgDocument.createElementNS(SVG_NAMESPACE, "g"); + pageDefs = svgDocument.createElementNS(SVG_NAMESPACE, "defs"); + pagesGroup.appendChild(pageDefs); + svgRoot.appendChild(pagesGroup); + + } + + /** + * @see org.apache.fop.render.Renderer#stopRenderer() + */ + public void stopRenderer() throws IOException { + totalWidth += sequenceWidth; + if (sequenceHeight > totalHeight) { + totalHeight = sequenceHeight; + } + + svgRoot.setAttributeNS(null, "width", "" + (totalWidth + 1)); + svgRoot.setAttributeNS(null, "height", "" + (totalHeight + 1)); + //svgRoot.setAttributeNS(null, "viewBox", "0 0 " + pageWidth + " " + pageHeight); + SVGTranscoder svgT = new SVGTranscoder(); + TranscoderInput input = new TranscoderInput(svgDocument); + TranscoderOutput output = + new TranscoderOutput(new OutputStreamWriter(ostream)); + try { + svgT.transcode(input, output); + } catch (TranscoderException e) { + getLogger().error("could not write svg file :" + e.getMessage(), e); + } + ostream.flush(); + ostream = null; + + svgDocument = null; + svgRoot = null; + currentPageG = null; + lastLink = null; + + totalWidth = 0; + totalHeight = 0; + + pageNumber = 0; + } + + /** + * @see org.apache.fop.render.Renderer#startPageSequence(Title) + */ + public void startPageSequence(Title seqTitle) { + totalWidth += sequenceWidth; + if (sequenceHeight > totalHeight) { + totalHeight = sequenceHeight; + } + sequenceWidth = 0; + sequenceHeight = 0; + if (seqTitle != null && docTitle == null) { + // convert first title to a string and set for svg document title + docTitle = seqTitle; + String str = convertTitleToString(seqTitle); + Element svgTitle = svgDocument.createElementNS(SVG_NAMESPACE, "title"); + Text strNode = svgDocument.createTextNode(str); + svgTitle.appendChild(strNode); + svgRoot.insertBefore(svgTitle, svgRoot.getFirstChild()); + } + } + + /** + * @see org.apache.fop.render.Renderer#renderPage(PageViewport) + */ + public void renderPage(PageViewport page) throws IOException, FOPException { + float lastWidth = pageWidth; + float lastHeight = pageHeight; + + Rectangle2D area = page.getViewArea(); + pageWidth = (float) area.getWidth() / 1000f; + pageHeight = (float) area.getHeight() / 1000f; + + // if there is a link from the last page + if (lastLink != null) { + lastLink.setAttributeNS(null, "xlink:href", "#svgView(viewBox(" + + totalWidth + ", " + + sequenceHeight + ", " + + pageWidth + ", " + + pageHeight + "))"); + pagesGroup.appendChild(lastLink); + } + + currentPageG = svgDocument.createElementNS(SVG_NAMESPACE, "svg"); + currentPageG.setAttributeNS(null, "viewbox", + "0 0 " + (int) pageWidth + " " + (int) pageHeight); + currentPageG.setAttributeNS(null, "width", + "" + ((int) pageWidth + 1)); + currentPageG.setAttributeNS(null, "height", + "" + ((int) pageHeight + 1)); + currentPageG.setAttributeNS(null, "id", "Page-" + pageNumber); + currentPageG.setAttributeNS(null, "style", "font-family:sanserif;font-size:12"); + pageDefs.appendChild(currentPageG); + + if (pageWidth > sequenceWidth) { + sequenceWidth = pageWidth; + } + sequenceHeight += pageHeight; + + Element border = + SVGUtilities.createRect(svgDocument, 0, 0, pageWidth, + pageHeight); + border.setAttributeNS(null, "style", "fill:none;stroke:black"); + currentPageG.appendChild(border); + + // render the page contents + super.renderPage(page); + + Element use = svgDocument.createElementNS(SVG_NAMESPACE, "use"); + use.setAttributeNS(null, "xlink:href", "#Page-" + pageNumber); + use.setAttributeNS(null, "x", "" + totalWidth); + use.setAttributeNS(null, "y", "" + (sequenceHeight - pageHeight)); + pagesGroup.appendChild(use); + + Element lastPageLink = svgDocument.createElementNS(SVG_NAMESPACE, "a"); + if (lastLink != null) { + lastPageLink.setAttributeNS(null, "xlink:href", lastViewbox); + } else { + lastPageLink.setAttributeNS(null, "xlink:href", + "#svgView(viewBox(" + + totalWidth + ", " + + (sequenceHeight - pageHeight) + ", " + + pageWidth + ", " + + pageHeight + "))"); + } + pagesGroup.appendChild(lastPageLink); + + // setup a link to the next page, only added when the + // next page is rendered + Element rect = SVGUtilities.createRect(svgDocument, totalWidth, + (sequenceHeight - pageHeight), pageWidth / 2, pageHeight); + rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); + lastPageLink.appendChild(rect); + + lastLink = svgDocument.createElementNS(SVG_NAMESPACE, "a"); + rect = SVGUtilities.createRect(svgDocument, + totalWidth + pageWidth / 2, + (sequenceHeight - pageHeight), pageWidth / 2, pageHeight); + rect.setAttributeNS(null, "style", "fill:blue;visibility:hidden"); + lastLink.appendChild(rect); + + lastViewbox = "#svgView(viewBox(" + + totalWidth + ", " + + (sequenceHeight - pageHeight) + ", " + + pageWidth + ", " + + pageHeight + "))"; + + pageNumber++; + + } + + /** + * Method renderForeignObject. + * @param fo the foreign object + */ + public void renderForeignObject(ForeignObject fo) { + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + userAgent.renderXML(context, doc, ns); + } + + /** + * @see org.apache.fop.render.XMLHandler#handleXML(RendererContext, Document, String) + */ + public void handleXML(RendererContext context, Document doc, + String ns) throws Exception { + if (SVG_NAMESPACE.equals(ns)) { + if (!(doc instanceof SVGDocument)) { + DOMImplementation impl = + SVGDOMImplementation.getDOMImplementation(); + doc = DOMUtilities.deepCloneDocument(doc, impl); + } + SVGSVGElement svg = ((SVGDocument) doc).getRootElement(); + Element view = svgDocument.createElementNS(SVG_NAMESPACE, "svg"); + Node newsvg = svgDocument.importNode(svg, true); + //view.setAttributeNS(null, "viewBox", "0 0 "); + view.setAttributeNS(null, "x", + "" + currentBlockIPPosition / 1000f); + view.setAttributeNS(null, "y", "" + currentBPPosition / 1000f); + + // this fixes a problem where the xmlns is repeated sometimes + Element ele = (Element) newsvg; + ele.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns", + SVG_NAMESPACE); + if (ele.hasAttributeNS(null, "xmlns")) { + ele.removeAttributeNS(null, "xmlns"); + } + + view.appendChild(newsvg); + currentPageG.appendChild(view); + } + } + + /** + * @see org.apache.fop.render.Renderer#renderLeader(Leader) + */ + public void renderLeader(Leader area) { + String style = "stroke:black;stroke-width:" + + (area.getRuleThickness() / 1000) + ";"; + switch (area.getRuleStyle()) { + case RuleStyle.DOTTED: + style += "stroke-dasharray:1,1"; + break; + case RuleStyle.DASHED: + style += "stroke-dasharray:5,1"; + break; + case RuleStyle.SOLID: + break; + case RuleStyle.DOUBLE: + break; + case RuleStyle.GROOVE: + break; + case RuleStyle.RIDGE: + break; + } + Element line = SVGUtilities.createLine(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + area.getOffset() + - area.getRuleThickness() / 2) / 1000, + (currentBlockIPPosition + area.getWidth()) / 1000, + (currentBPPosition + area.getOffset() + - area.getRuleThickness() / 2) / 1000); + line.setAttributeNS(null, "style", style); + currentPageG.appendChild(line); + + super.renderLeader(area); + } + + /** + * @see org.apache.fop.render.Renderer#renderWord(Word) + */ + public void renderWord(Word word) { + Element text = SVGUtilities.createText(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + word.getOffset()) / 1000, + word.getWord()); + currentPageG.appendChild(text); + + super.renderWord(word); + } + + /** + * @see org.apache.fop.render.Renderer#renderCharacter(Character) + */ + public void renderCharacter(org.apache.fop.area.inline.Character ch) { + Element text = SVGUtilities.createText(svgDocument, + currentBlockIPPosition / 1000, + (currentBPPosition + ch.getOffset()) / 1000, + "" + ch.getChar()); + currentPageG.appendChild(text); + + super.renderCharacter(ch); + } +} + diff --git a/src/java/org/apache/fop/render/txt/TXTRenderer.java b/src/java/org/apache/fop/render/txt/TXTRenderer.java new file mode 100644 index 000000000..df610d994 --- /dev/null +++ b/src/java/org/apache/fop/render/txt/TXTRenderer.java @@ -0,0 +1,172 @@ +/* + * $Id: TXTRenderer.java,v 1.18 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.txt; + +// FOP +import org.apache.fop.render.PrintRenderer; +import org.apache.fop.render.pcl.PCLStream; + +/** + * Renderer that renders areas to plain text + * + * Created by Arthur E Welch III while at M&I EastPoint Technology + * Modified by Mark Lillywhite mark-fop@inomial.com to use the new + * Renderer interface. + */ +public class TXTRenderer extends PrintRenderer { + + /** + * the current stream to add Text commands to + */ + private PCLStream currentStream; + + private int pageHeight = 7920; + + // These variables control the virtual paggination functionality. + private int curdiv = 0; + private int divisions = -1; + private int paperheight = -1; // Paper height in decipoints? + private int orientation = -1; // -1=default/unknown, 0=portrait, 1=landscape. + private int topmargin = -1; // Top margin in decipoints? + private int leftmargin = -1; // Left margin in decipoints? + private int fullmargin = 0; + private final boolean debug = false; + + // Variables for rendering text. + private StringBuffer charData[]; + private StringBuffer decoData[]; + private float textCPI = 16.67f; + private float textLPI = 8; + private int maxX = (int)(8.5f * textCPI + 1); + private int maxY = (int)(11f * textLPI + 1); + private float xFactor; + private float yFactor; + /** + * Every line except the last line on a page (which will end with + * pageEnding) will be terminated with this string. + */ + private String lineEnding = "\r\n"; + /** + * Every page except the last one will end with this string. + */ + private String pageEnding = "\f"; + /** + * If true then graphics/decorations will not be rendered - text only. + */ + private boolean suppressGraphics = false; + private boolean firstPage = false; + + /** + * Set the TXT document's producer + * + * @param producer string indicating application producing PDF + */ + public void setProducer(String producer) { + } + + + private void addStr(int row, int col, String str, boolean ischar) { + if (debug) { + getLogger().debug("TXTRenderer.addStr(" + row + ", " + col + + ", \"" + str + "\", " + ischar + ")"); + } + if (suppressGraphics && !ischar) { + return; + } + StringBuffer sb; + if (row < 0) { + row = 0; + } + if (ischar) { + sb = charData[row]; + } else { + sb = decoData[row]; + } + if (sb == null) { + sb = new StringBuffer(); + } + if ((col + str.length()) > maxX) { + col = maxX - str.length(); + } + if (col < 0) { + col = 0; + if (str.length() > maxX) { + str = str.substring(0, maxX); + } + } + // Pad to col + for (int countr = sb.length(); countr < col; countr++) { + sb.append(' '); + } + if (debug) { + getLogger().debug("TXTRenderer.addStr() sb.length()=" + + sb.length()); + } + for (int countr = col; countr < (col + str.length()); countr++) { + if (countr >= sb.length()) { + sb.append(str.charAt(countr - col)); + } else { + if (debug) { + getLogger().debug("TXTRenderer.addStr() sb.length()=" + + sb.length() + " countr=" + countr); + } + sb.setCharAt(countr, str.charAt(countr - col)); + } + } + + if (ischar) { + charData[row] = sb; + } else { + decoData[row] = sb; + } + } + +} diff --git a/src/java/org/apache/fop/render/txt/TXTStream.java b/src/java/org/apache/fop/render/txt/TXTStream.java new file mode 100644 index 000000000..df45c47ba --- /dev/null +++ b/src/java/org/apache/fop/render/txt/TXTStream.java @@ -0,0 +1,98 @@ +/* + * $Id: TXTStream.java,v 1.4 2003/03/07 09:46:32 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.txt; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Helper class for text streams. + */ +public class TXTStream { + + private OutputStream out = null; + private boolean doOutput = true; + + /** + * Main constructor. + * @param os OutputStream to write to + */ + public TXTStream(OutputStream os) { + out = os; + } + + /** + * Adds a String to the OutputStream + * @param str String to add + */ + public void add(String str) { + if (!doOutput) { + return; + } + + try { + byte buff[] = str.getBytes("UTF-8"); + out.write(buff); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + /** + * Controls whether output is actually written. + * @param doout true to enable output, false to suppress + */ + public void setDoOutput(boolean doout) { + doOutput = doout; + } + +} + diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java new file mode 100644 index 000000000..a2ca49b3c --- /dev/null +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -0,0 +1,536 @@ +/* + * $Id: XMLRenderer.java,v 1.43 2003/03/07 09:46:34 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.xml; + +// Java +import java.io.IOException; +import java.io.PrintWriter; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.Iterator; +import java.awt.geom.Rectangle2D; + +// XML +import org.w3c.dom.Document; + +// FOP +import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.XMLHandler; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.BeforeFloat; +import org.apache.fop.area.Block; +import org.apache.fop.area.BodyRegion; +import org.apache.fop.area.Flow; +import org.apache.fop.area.Footnote; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.MainReference; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.Span; +import org.apache.fop.area.Title; +import org.apache.fop.area.Trait; +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; +import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.Word; +import org.apache.fop.fo.properties.RuleStyle; + +/** + * Renderer that renders areas to XML for debugging purposes. + * This creates an xml that contains the information of the area + * tree. It does not output any state or derived information. + * The output can be used to build a new area tree (@see AreaTreeBuilder) + * which can be rendered to any renderer. + */ +public class XMLRenderer extends AbstractRenderer { + + /** XML MIME type */ + public static final String XML_MIME_TYPE = "text/xml"; + + private boolean startedSequence = false; + private RendererContext context; + + /** + * @see org.apache.fop.render.Renderer#setProducer(String) + */ + public void setProducer(String producer) { + } + + /** + * indentation to use for pretty-printing the XML + */ + protected int indent = 0; + + /** + * the application producing the XML + */ + protected String producer; + + /** + * the writer used to output the XML + */ + protected PrintWriter writer; + + /** + * options + */ + private boolean consistentOutput = false; + + /** + * Creates a new XML renderer. + */ + public XMLRenderer() { + context = new RendererContext(XML_MIME_TYPE); + } + + /** + * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent) + */ + public void setUserAgent(FOUserAgent agent) { + super.setUserAgent(agent); + + // + //userAgent.addExtensionHandler(); + XMLHandler handler = new XMLXMLHandler(); + userAgent.setDefaultXMLHandler(XML_MIME_TYPE, handler); + String svg = "http://www.w3.org/2000/svg"; + userAgent.addXMLHandler(XML_MIME_TYPE, svg, handler); + } + + /** + * write out spaces to make indent + */ + protected void writeIndent() { + StringBuffer s = new StringBuffer(); + for (int i = 0; i < this.indent; i++) { + s = s.append(" "); + } + this.writer.write(s.toString()); + } + + /** + * write out an element + * + * @param element the full text of the element including tags + */ + protected void writeElement(String element) { + writeIndent(); + this.writer.write(element + "\n"); + } + + /** + * write out an empty-element-tag + * + * @param tag the text of the tag + */ + protected void writeEmptyElementTag(String tag) { + writeIndent(); + this.writer.write(tag + "\n"); + } + + /** + * write out an end tag + * + * @param tag the text of the tag + */ + protected void writeEndTag(String tag) { + this.indent--; + writeIndent(); + this.writer.write(tag + "\n"); + } + + /** + * write out a start tag + * + * @param tag the text of the tag + */ + protected void writeStartTag(String tag) { + writeIndent(); + this.writer.write(tag + "\n"); + this.indent++; + } + + /** + * set up the font info + * + * @param fontInfo the font info object to set up + */ + public void setupFontInfo(FontInfo fontInfo) { + + /* use PDF's font setup to get PDF metrics */ + org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); + } + + private boolean isCoarseXml() { + return ((Boolean) options.get("fineDetail")).booleanValue(); + } + + /** + * @see org.apache.fop.render.Renderer#startRenderer(OutputStream) + */ + public void startRenderer(OutputStream outputStream) + throws IOException { + getLogger().debug("rendering areas to XML"); + this.writer = new PrintWriter(outputStream); + this.writer.write("\n" + + "\n"); + writeStartTag(""); + } + + /** + * @see org.apache.fop.render.Renderer#stopRenderer() + */ + public void stopRenderer() throws IOException { + writeEndTag(""); + writeEndTag(""); + this.writer.flush(); + getLogger().debug("written out XML"); + } + + /** + * @see org.apache.fop.render.Renderer#renderPage(PageViewport) + */ + public void renderPage(PageViewport page) throws IOException, FOPException { + writeStartTag(""); + writeStartTag(""); + super.renderPage(page); + writeEndTag(""); + writeEndTag(""); + } + + private String createString(Rectangle2D rect) { + return "" + (int) rect.getX() + " " + (int) rect.getY() + " " + + (int) rect.getWidth() + " " + (int) rect.getHeight(); + } + + /** + * @see org.apache.fop.render.Renderer#startPageSequence(Title) + */ + public void startPageSequence(Title seqTitle) { + if (startedSequence) { + writeEndTag(""); + } + startedSequence = true; + writeStartTag(""); + if (seqTitle != null) { + writeStartTag(""); + List children = seqTitle.getInlineAreas(); + + for (int count = 0; count < children.size(); count++) { + InlineArea inline = (InlineArea) children.get(count); + inline.render(this); + } + + writeEndTag(""); + } + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderRegionViewport(RegionViewport) + */ + protected void renderRegionViewport(RegionViewport port) { + if (port != null) { + writeStartTag(""); + RegionReference region = port.getRegion(); + if (region.getRegionClass() == RegionReference.BEFORE) { + writeStartTag(""); + renderRegion(region); + writeEndTag(""); + } else if (region.getRegionClass() == RegionReference.START) { + writeStartTag(""); + renderRegion(region); + writeEndTag(""); + } else if (region.getRegionClass() == RegionReference.BODY) { + writeStartTag(""); + renderBodyRegion((BodyRegion) region); + writeEndTag(""); + } else if (region.getRegionClass() == RegionReference.END) { + writeStartTag(""); + renderRegion(region); + writeEndTag(""); + } else if (region.getRegionClass() == RegionReference.AFTER) { + writeStartTag(""); + renderRegion(region); + writeEndTag(""); + } + writeEndTag(""); + } + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderBeforeFloat(BeforeFloat) + */ + protected void renderBeforeFloat(BeforeFloat bf) { + writeStartTag(""); + super.renderBeforeFloat(bf); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderFootnote(Footnote) + */ + protected void renderFootnote(Footnote footnote) { + writeStartTag(""); + super.renderFootnote(footnote); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderMainReference(MainReference) + */ + protected void renderMainReference(MainReference mr) { + writeStartTag(""); + + Span span = null; + List spans = mr.getSpans(); + for (int count = 0; count < spans.size(); count++) { + span = (Span) spans.get(count); + writeStartTag(""); + for (int c = 0; c < span.getColumnCount(); c++) { + Flow flow = (Flow) span.getFlow(c); + + renderFlow(flow); + } + writeEndTag(""); + } + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderFlow(Flow) + */ + protected void renderFlow(Flow flow) { + // the normal flow reference area contains stacked blocks + writeStartTag(""); + super.renderFlow(flow); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderBlock(Block) + */ + protected void renderBlock(Block block) { + String prop = ""; + Map map = block.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; + } + writeStartTag(""); + super.renderBlock(block); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderLineArea(LineArea) + */ + protected void renderLineArea(LineArea line) { + String prop = ""; + Map map = line.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; + } + writeStartTag(""); + super.renderLineArea(line); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.Renderer#renderViewport(Viewport) + */ + public void renderViewport(Viewport viewport) { + writeStartTag(""); + super.renderViewport(viewport); + writeEndTag(""); + } + + /** + * Renders an image + * @param image the image + */ + public void renderImage(Image image) { + writeElement(""); + } + + /** + * @see org.apache.fop.render.Renderer#renderContainer(Container) + */ + public void renderContainer(Container cont) { + writeStartTag(""); + + super.renderContainer(cont); + writeEndTag(""); + } + + /** + * Renders an fo:foreing-object. + * @param fo the foreign object + */ + public void renderForeignObject(ForeignObject fo) { + writeStartTag(""); + Document doc = fo.getDocument(); + String ns = fo.getNameSpace(); + context.setProperty(XMLXMLHandler.WRITER, writer); + userAgent.renderXML(context, doc, ns); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.Renderer#renderCharacter(Character) + */ + public void renderCharacter(org.apache.fop.area.inline.Character ch) { + String prop = ""; + Map map = ch.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; + } + writeElement("" + ch.getChar() + ""); + } + + /** + * @see org.apache.fop.render.Renderer#renderInlineSpace(Space) + */ + public void renderInlineSpace(Space space) { + writeElement(""); + } + + /** + * @see org.apache.fop.render.Renderer#renderWord(Word) + */ + public void renderWord(Word word) { + String prop = ""; + Map map = word.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; + } + writeElement("" + word.getWord() + ""); + super.renderWord(word); + } + + /** + * @see org.apache.fop.render.Renderer#renderInlineParent(InlineParent) + */ + public void renderInlineParent(InlineParent ip) { + String prop = ""; + Map map = ip.getTraits(); + if (map != null) { + prop = " props=\"" + getPropString(map) + "\""; + } + writeStartTag(""); + super.renderInlineParent(ip); + writeEndTag(""); + } + + /** + * @see org.apache.fop.render.Renderer#renderLeader(Leader) + */ + public void renderLeader(Leader area) { + String style = "solid"; + switch (area.getRuleStyle()) { + case RuleStyle.DOTTED: + style = "dotted"; + break; + case RuleStyle.DASHED: + style = "dashed"; + break; + case RuleStyle.SOLID: + break; + case RuleStyle.DOUBLE: + style = "double"; + break; + case RuleStyle.GROOVE: + style = "groove"; + break; + case RuleStyle.RIDGE: + style = "ridge"; + break; + } + writeElement(""); + super.renderLeader(area); + } + + /** + * Builds a String with attributes from the trait map. + * @param traitMap the trait map + * @return String the generated attributes + */ + protected String getPropString(Map traitMap) { + StringBuffer strbuf = new StringBuffer(); + Iterator iter = traitMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry traitEntry = (Map.Entry) iter.next(); + strbuf.append(Trait.getTraitName(traitEntry.getKey())); + strbuf.append(':'); + strbuf.append(traitEntry.getValue().toString()); + strbuf.append(';'); + } + return strbuf.toString(); + } + +} + diff --git a/src/java/org/apache/fop/render/xml/XMLXMLHandler.java b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java new file mode 100644 index 000000000..9c65d6269 --- /dev/null +++ b/src/java/org/apache/fop/render/xml/XMLXMLHandler.java @@ -0,0 +1,213 @@ +/* + * $Id: XMLXMLHandler.java,v 1.3 2003/03/07 09:46:34 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.render.xml; + +import org.apache.fop.render.XMLHandler; +import org.apache.fop.render.RendererContext; + +import org.apache.batik.dom.util.DOMUtilities; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Attr; + +import java.io.Writer; +import java.io.IOException; + +/** + * XML handler for the XML renderer. + */ +public class XMLXMLHandler implements XMLHandler { + + /** Key for getting the Writer from the RendererContext */ + public static final String WRITER = "writer"; + + /** + * @see org.apache.fop.render.XMLHandler#handleXML(RendererContext, Document, String) + */ + public void handleXML(RendererContext context, Document doc, + String ns) throws Exception { + Writer writer = (Writer) context.getProperty(WRITER); + + String svg = "http://www.w3.org/2000/svg"; + // actually both do the same thing but one requires + // batik + if (svg.equals(ns)) { + DOMUtilities.writeDocument(doc, writer); + } else { + writeDocument(doc, writer); + } + writer.write("\n"); + } + + /** + * Writes the given document using the given writer. + * @param doc DOM document + * @param writer Writer to write to + * @throws IOException In case of an I/O problem + */ + public static void writeDocument(Document doc, + Writer writer) throws IOException { + for (Node n = doc.getFirstChild(); n != null; + n = n.getNextSibling()) { + writeNode(n, writer); + } + } + + /** + * Writes a node using the given writer. + * @param node node to serialize + * @param writer Writer to write to + * @throws IOException In case of an I/O problem + */ + public static void writeNode(Node node, Writer writer) throws IOException { + switch (node.getNodeType()) { + case Node.ELEMENT_NODE: + writer.write("<"); + writer.write(node.getNodeName()); + + if (node.hasAttributes()) { + NamedNodeMap attr = node.getAttributes(); + int len = attr.getLength(); + for (int i = 0; i < len; i++) { + Attr a = (Attr) attr.item(i); + writer.write(" "); + writer.write(a.getNodeName()); + writer.write("=\""); + writer.write(contentToString(a.getNodeValue())); + writer.write("\""); + } + } + + Node c = node.getFirstChild(); + if (c != null) { + writer.write(">"); + for (; c != null; c = c.getNextSibling()) { + writeNode(c, writer); + } + writer.write(""); + } else { + writer.write("/>"); + } + break; + case Node.TEXT_NODE: + writer.write(contentToString(node.getNodeValue())); + break; + case Node.CDATA_SECTION_NODE: + writer.write(""); + break; + case Node.ENTITY_REFERENCE_NODE: + writer.write("&"); + writer.write(node.getNodeName()); + writer.write(";"); + break; + case Node.PROCESSING_INSTRUCTION_NODE: + writer.write(""); + break; + case Node.COMMENT_NODE: + writer.write(""); + break; + case Node.DOCUMENT_TYPE_NODE: + break; + default: + throw new IllegalArgumentException("Unexpected node type (" + + node.getNodeType() + ")"); + } + } + + /** + * Returns the given content value transformed to replace invalid + * characters with entities. + * @param s content value + * @return encoded value + */ + public static String contentToString(String s) { + StringBuffer result = new StringBuffer(); + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + switch (c) { + case '<': + result.append("<"); + break; + case '>': + result.append(">"); + break; + case '&': + result.append("&"); + break; + case '"': + result.append("""); + break; + case '\'': + result.append("'"); + break; + default: + result.append(c); + } + } + + return result.toString(); + } + +} + diff --git a/src/java/org/apache/fop/render/xml/package.html b/src/java/org/apache/fop/render/xml/package.html new file mode 100644 index 000000000..ecabe3547 --- /dev/null +++ b/src/java/org/apache/fop/render/xml/package.html @@ -0,0 +1,6 @@ + +org.apache.fop.render.xml Package + +

classes for rendering to XML for debugging

+ + \ No newline at end of file diff --git a/src/java/org/apache/fop/rtf/renderer/RTFHandler.java b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java new file mode 100644 index 000000000..610aac25f --- /dev/null +++ b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java @@ -0,0 +1,204 @@ +/* + * $Id: RTFHandler.java,v 1.4 2003/03/07 09:47:56 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.rtf.renderer; + +// Java +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.IOException; + +// XML +import org.xml.sax.SAXException; + +// FOP +import org.apache.fop.apps.StructureHandler; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.apps.FOPException; + +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.LayoutMasterSet; +import org.apache.fop.fo.Title; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.Flow; + +// JFOR +import org.jfor.jfor.rtflib.rtfdoc.RtfFile; +import org.jfor.jfor.rtflib.rtfdoc.RtfSection; +import org.jfor.jfor.rtflib.rtfdoc.RtfParagraph; +import org.jfor.jfor.rtflib.rtfdoc.RtfDocumentArea; + +/** + * RTF Handler: generates RTF output using the structure events from + * the FO Tree sent to this structure handler. + * + * @author bdelacretaz@apache.org + */ +public class RTFHandler extends StructureHandler { + + private FontInfo fontInfo = new FontInfo(); + private RtfFile rtfFile; + private final OutputStream os; + private RtfSection sect; + private RtfDocumentArea docArea; + private RtfParagraph para; + private boolean warned = false; + + private static final String ALPHA_WARNING = "WARNING: RTF renderer is " + + "veryveryalpha at this time, see class org.apache.fop.rtf.renderer.RTFHandler"; + + /** + * Creates a new RTF structure handler. + * @param os OutputStream to write to + */ + public RTFHandler(OutputStream os) { + this.os = os; + // use pdf fonts for now, this is only for resolving names + org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); + System.err.println(ALPHA_WARNING); + } + + /** + * @see org.apache.fop.apps.StructureHandler#getFontInfo() + */ + public FontInfo getFontInfo() { + return this.fontInfo; + } + + /** + * @see org.apache.fop.apps.StructureHandler#startDocument() + */ + public void startDocument() throws SAXException { + // FIXME sections should be created + try { + rtfFile = new RtfFile(new OutputStreamWriter(os)); + docArea = rtfFile.startDocumentArea(); + } catch (IOException ioe) { + // FIXME could we throw Exception in all StructureHandler events? + throw new SAXException("IOException: " + ioe); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler#endDocument() + */ + public void endDocument() throws SAXException { + try { + rtfFile.flush(); + } catch (IOException ioe) { + // FIXME could we throw Exception in all StructureHandler events? + throw new SAXException("IOException: " + ioe); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler + */ + public void startPageSequence(PageSequence pageSeq, Title seqTitle, LayoutMasterSet lms) { + try { + sect = docArea.newSection(); + if (!warned) { + sect.newParagraph().newText(ALPHA_WARNING); + warned = true; + } + } catch (IOException ioe) { + // FIXME could we throw Exception in all StructureHandler events? + throw new Error("IOException: " + ioe); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler#endPageSequence(PageSequence) + */ + public void endPageSequence(PageSequence pageSeq) throws FOPException { + } + + /** + * @see org.apache.fop.apps.StructureHandler#startFlow(Flow) + */ + public void startFlow(Flow fl) { + } + + /** + * @see org.apache.fop.apps.StructureHandler#endFlow(Flow) + */ + public void endFlow(Flow fl) { + } + + /** + * @see org.apache.fop.apps.StructureHandler#startBlock(Block) + */ + public void startBlock(Block bl) { + try { + para = sect.newParagraph(); + } catch (IOException ioe) { + // FIXME could we throw Exception in all StructureHandler events? + throw new Error("IOException: " + ioe); + } + } + + /** + * @see org.apache.fop.apps.StructureHandler#endBlock(Block) + */ + public void endBlock(Block bl) { + } + + /** + * @see org.apache.fop.apps.StructureHandler#characters(char[], int, int) + */ + public void characters(char data[], int start, int length) { + try { + para.newText(new String(data, start, length)); + } catch (IOException ioe) { + // FIXME could we throw Exception in all StructureHandler events? + throw new Error("IOException: " + ioe); + } + } +} diff --git a/src/java/org/apache/fop/servlet/FopPrintServlet.java b/src/java/org/apache/fop/servlet/FopPrintServlet.java new file mode 100644 index 000000000..da226aba0 --- /dev/null +++ b/src/java/org/apache/fop/servlet/FopPrintServlet.java @@ -0,0 +1,317 @@ +/* + * $Id: FopPrintServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.servlet; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.util.List; + +import java.awt.print.PrinterJob; +import java.awt.print.PrinterException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.TransformerFactory; + +import org.xml.sax.InputSource; + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; + +// FOP +import org.apache.fop.apps.Driver; +import org.apache.fop.apps.FOPException; +import org.apache.fop.area.PageViewport; +import org.apache.fop.apps.XSLTInputHandler; +import org.apache.fop.render.awt.AWTRenderer; + +/** + * Example servlet to generate a fop printout from a servlet. + * Printing goes to the default printer on host where the servlet executes. + * Servlet param is: + *
    + *
  • fo: the path to a XSL-FO file to render + *
+ * or + *
    + *
  • xml: the path to an XML file to render
  • + *
  • xslt: the path to an XSLT file that can transform the above XML to XSL-FO
  • + *
+ *
+ * Example URL: http://servername/fop/servlet/FopPrintServlet?fo=readme.fo + *
+ * Example URL: http://servername/fop/servlet/FopPrintServlet?xml=data.xml&xsl=format.xsl + * + * @author Apache XML FOP Development Team + * @version $Id: FopPrintServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $ + * @todo Doesn't work since there's no AWTRenderer at the moment. Revisit when + * available. + * @todo Don't use XSLTInputHandler anymore + * @todo Ev. add caching mechanism for Templates objects + */ +public class FopPrintServlet extends HttpServlet { + + /** Name of the parameter used for the XSL-FO file */ + protected static final String FO_REQUEST_PARAM = "fo"; + /** Name of the parameter used for the XML file */ + protected static final String XML_REQUEST_PARAM = "xml"; + /** Name of the parameter used for the XSLT file */ + protected static final String XSLT_REQUEST_PARAM = "xslt"; + + /** Logger to give to FOP */ + protected Logger log = null; + /** The TransformerFactory to use to create Transformer instances */ + protected TransformerFactory transFactory = null; + + /** + * @see javax.servlet.GenericServlet#init() + */ + public void init() throws ServletException { + this.log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN); + this.transFactory = TransformerFactory.newInstance(); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse) + */ + public void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException { + if (log == null) { + log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN); + } + + try { + String foParam = request.getParameter(FO_REQUEST_PARAM); + String xmlParam = request.getParameter(XML_REQUEST_PARAM); + String xsltParam = request.getParameter(XSLT_REQUEST_PARAM); + + if (foParam != null) { + InputStream file = new java.io.FileInputStream(foParam); + renderFO(new InputSource(file), response); + } else if ((xmlParam != null) && (xsltParam != null)) { + XSLTInputHandler input = + new XSLTInputHandler(new File(xmlParam), + new File(xsltParam)); + renderXML(input, response); + } else { + response.setContentType("text/html"); + + PrintWriter out = response.getWriter(); + out.println("Error\n" + + "

FopServlet Error

\n" + + "

No 'fo' or 'xml/xsl' " + + "request param given.

\n"); + } + } catch (ServletException ex) { + throw ex; + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + /** + * Renders an FO inputsource to the default printer. + * @param foFile The XSL-FO file + * @param response Response to write to + * @throws ServletException In case of a problem + */ + public void renderFO(InputSource foFile, + HttpServletResponse response) throws ServletException { + try { + Driver driver = new Driver(foFile, null); + PrinterJob pj = PrinterJob.getPrinterJob(); + PrintRenderer renderer = new PrintRenderer(pj); + + driver.enableLogging(log); + driver.setRenderer(renderer); + driver.run(); + + reportOK (response); + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + /** + * Renders an FO generated using an XML and a stylesheet to the default printer. + * @param input XSLTInputHandler to use + * @param response Response to write to + * @throws ServletException In case of a problem + */ + public void renderXML(XSLTInputHandler input, + HttpServletResponse response) throws ServletException { + try { + Driver driver = new Driver(); + PrinterJob pj = PrinterJob.getPrinterJob(); + PrintRenderer renderer = new PrintRenderer(pj); + + pj.setCopies(1); + + driver.enableLogging(log); + driver.setRenderer(renderer); + driver.render(input.getParser(), input.getInputSource()); + + reportOK (response); + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + // private helper, tell (browser) user that file printed + private void reportOK(HttpServletResponse response) + throws ServletException { + String sMsg = "Success\n" + + "

FopPrintServlet:

" + + "

The requested data was printed

"; + + response.setContentType("text/html"); + response.setContentLength(sMsg.length()); + + try { + PrintWriter out = response.getWriter(); + out.println(sMsg); + out.flush(); + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + // This is stolen from PrintStarter + class PrintRenderer extends AWTRenderer { + + private static final int EVEN_AND_ALL = 0; + private static final int EVEN = 1; + private static final int ODD = 2; + + private int startNumber; + private int endNumber; + private int mode = EVEN_AND_ALL; + private int copies = 1; + private PrinterJob printerJob; + + PrintRenderer(PrinterJob printerJob) { + super(null); + + this.printerJob = printerJob; + startNumber = 0 ; + endNumber = -1; + + printerJob.setPageable(this); + + mode = EVEN_AND_ALL; + String str = System.getProperty("even"); + if (str != null) { + mode = Boolean.valueOf(str).booleanValue() ? EVEN : ODD; + } + } + + public void stopRenderer() throws IOException { + super.stopRenderer(); + + if (endNumber == -1) { + endNumber = getPageCount(); + } + + List numbers = getInvalidPageNumbers(); + for (int i = numbers.size() - 1; i > -1; i--) { + //removePage( + // Integer.parseInt((String) numbers.elementAt(i))); + } + + try { + printerJob.print(); + } catch (PrinterException e) { + e.printStackTrace(); + throw new IOException("Unable to print: " + + e.getClass().getName() + ": " + e.getMessage()); + } + } + + public void renderPage(PageViewport page) throws IOException, FOPException { + pageWidth = (int)((float) page.getViewArea().getWidth() / 1000f); + pageHeight = (int)((float) page.getViewArea().getHeight() / 1000f); + super.renderPage(page); + } + + + private List getInvalidPageNumbers() { + + List list = new java.util.ArrayList(); + int max = getPageCount(); + boolean isValid; + for (int i = 0; i < max; i++) { + isValid = true; + if (i < startNumber || i > endNumber) { + isValid = false; + } else if (mode != EVEN_AND_ALL) { + if (mode == EVEN && ((i + 1) % 2 != 0)) { + isValid = false; + } else if (mode == ODD && ((i + 1) % 2 != 1)) { + isValid = false; + } + } + + if (!isValid) { + list.add(Integer.toString(i)); + } + } + + return list; + } + } // class PrintRenderer + +} + diff --git a/src/java/org/apache/fop/servlet/FopServlet.java b/src/java/org/apache/fop/servlet/FopServlet.java new file mode 100644 index 000000000..cab0de055 --- /dev/null +++ b/src/java/org/apache/fop/servlet/FopServlet.java @@ -0,0 +1,255 @@ +/* + * $Id: FopServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.servlet; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; + +//FOP +import org.apache.fop.apps.Driver; +import org.apache.fop.apps.FOPException; + +/** + * Example servlet to generate a PDF from a servlet. + *
+ * Servlet param is: + *
    + *
  • fo: the path to a XSL-FO file to render + *
+ * or + *
    + *
  • xml: the path to an XML file to render
  • + *
  • xslt: the path to an XSLT file that can transform the above XML to XSL-FO
  • + *
+ *
+ * Example URL: http://servername/fop/servlet/FopServlet?fo=readme.fo + *
+ * Example URL: http://servername/fop/servlet/FopServlet?xml=data.xml&xslt=format.xsl + *
+ * For this to work with Internet Explorer, you might need to append "&ext=.pdf" + * to the URL. + * + * @author Apache XML FOP Development Team + * @version $Id: FopServlet.java,v 1.2 2003/03/07 09:48:05 jeremias Exp $ + * @todo Ev. add caching mechanism for Templates objects + */ +public class FopServlet extends HttpServlet { + + /** Name of the parameter used for the XSL-FO file */ + protected static final String FO_REQUEST_PARAM = "fo"; + /** Name of the parameter used for the XML file */ + protected static final String XML_REQUEST_PARAM = "xml"; + /** Name of the parameter used for the XSLT file */ + protected static final String XSLT_REQUEST_PARAM = "xslt"; + + /** Logger to give to FOP */ + protected Logger log = null; + /** The TransformerFactory to use to create Transformer instances */ + protected TransformerFactory transFactory = null; + + /** + * @see javax.servlet.GenericServlet#init() + */ + public void init() throws ServletException { + this.log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN); + this.transFactory = TransformerFactory.newInstance(); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse) + */ + public void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException { + try { + //Get parameters + String foParam = request.getParameter(FO_REQUEST_PARAM); + String xmlParam = request.getParameter(XML_REQUEST_PARAM); + String xsltParam = request.getParameter(XSLT_REQUEST_PARAM); + + //Analyze parameters and decide with method to use + byte[] content = null; + if (foParam != null) { + content = renderFO(foParam); + } else if ((xmlParam != null) && (xsltParam != null)) { + content = renderXML(xmlParam, xsltParam); + } else { + PrintWriter out = response.getWriter(); + out.println("Error\n" + + "

FopServlet Error

No 'fo' " + + "request param given."); + } + + if (content != null) { + //Send the result back to the client + response.setContentType("application/pdf"); + response.setContentLength(content.length); + response.getOutputStream().write(content); + response.getOutputStream().flush(); + } + + } catch (Exception ex) { + throw new ServletException(ex); + } + } + + /** + * Converts a String parameter to a JAXP Source object. + * @param param a String parameter + * @return Source the generated Source object + */ + protected Source convertString2Source(String param) { + return new StreamSource(new File(param)); + } + + /** + * Renders an XSL-FO file into a PDF file. The PDF is written to a byte + * array that is returned as the method's result. + * @param fo the XSL-FO file + * @return byte[] the rendered PDF file + * @throws FOPException If an error occurs during the rendering of the + * XSL-FO + * @throws TransformerException If an error occurs while parsing the input + * file + */ + protected byte[] renderFO(String fo) + throws FOPException, TransformerException { + + //Setup source + Source foSrc = convertString2Source(fo); + + //Setup the identity transformation + Transformer transformer = this.transFactory.newTransformer(); + + //Start transformation and rendering process + return render(foSrc, transformer); + } + + /** + * Renders an XML file into a PDF file by applying a stylesheet + * that converts the XML to XSL-FO. The PDF is written to a byte array + * that is returned as the method's result. + * @param xml the XML file + * @param xslt the XSLT file + * @return byte[] the rendered PDF file + * @throws FOPException If an error occurs during the rendering of the + * XSL-FO + * @throws TransformerException If an error occurs during XSL + * transformation + */ + protected byte[] renderXML(String xml, String xslt) + throws FOPException, TransformerException { + + //Setup sources + Source xmlSrc = convertString2Source(xml); + Source xsltSrc = convertString2Source(xslt); + + //Setup the XSL transformation + Transformer transformer = this.transFactory.newTransformer(xsltSrc); + + //Start transformation and rendering process + return render(xmlSrc, transformer); + } + + /** + * Renders an input file (XML or XSL-FO) into a PDF file. It uses the JAXP + * transformer given to optionally transform the input document to XSL-FO. + * The transformer may be an identity transformer in which case the input + * must already be XSL-FO. The PDF is written to a byte array that is + * returned as the method's result. + * @param src Input XML or XSL-FO + * @param transformer Transformer to use for optional transformation + * @return byte[] the rendered PDF file + * @throws FOPException If an error occurs during the rendering of the + * XSL-FO + * @throws TransformerException If an error occurs during XSL + * transformation + */ + protected byte[] render(Source src, Transformer transformer) + throws FOPException, TransformerException { + + //Setup FOP + Driver driver = new Driver(); + driver.enableLogging(this.log); + driver.setRenderer(Driver.RENDER_PDF); + driver.initialize(); + + //Setup output + ByteArrayOutputStream out = new ByteArrayOutputStream(); + driver.setOutputStream(out); + + //Make sure the XSL transformation's result is piped through to FOP + Result res = new SAXResult(driver.getContentHandler()); + + //Start the transformation and rendering process + transformer.transform(src, res); + + //Return the result + return out.toByteArray(); + } + +} diff --git a/src/java/org/apache/fop/servlet/package.html b/src/java/org/apache/fop/servlet/package.html new file mode 100644 index 000000000..4e09e188b --- /dev/null +++ b/src/java/org/apache/fop/servlet/package.html @@ -0,0 +1,6 @@ + + org.apache.fop.servlet Package + +

This package contains two sample FOP servlets.

+ + diff --git a/src/java/org/apache/fop/svg/PDFAElementBridge.java b/src/java/org/apache/fop/svg/PDFAElementBridge.java new file mode 100644 index 000000000..2969501f3 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFAElementBridge.java @@ -0,0 +1,124 @@ +/* + * $Id: PDFAElementBridge.java,v 1.6 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.awt.geom.AffineTransform; + +import org.apache.batik.bridge.AbstractGraphicsNodeBridge; +import org.apache.batik.bridge.BridgeContext; + +import org.apache.batik.gvt.GraphicsNode; + +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGAElement; + +/** + * Bridge class for the <a> element. + * + * @author Keiron Liddle + */ +public class PDFAElementBridge extends AbstractGraphicsNodeBridge { + private AffineTransform transform; + + /** + * Constructs a new bridge for the <a> element. + */ + public PDFAElementBridge() { + } + + /** + * Set the current transform of this element. + * @param tf the transform + */ + public void setCurrentTransform(AffineTransform tf) { + transform = tf; + } + + /** + * Returns 'a'. + * @return the name of this node + */ + public String getLocalName() { + return SVG_A_TAG; + } + + /** + * Creates a CompositeGraphicsNode. + * @return a new PDFANode + */ + protected GraphicsNode instantiateGraphicsNode() { + return new PDFANode(); + } + + /** + * Builds using the specified BridgeContext and element, the + * specified graphics node. + * + * @param ctx the bridge context to use + * @param e the element that describes the graphics node to build + * @return node the new graphics node + */ + public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { + PDFANode aNode = (PDFANode)super.createGraphicsNode(ctx, e); + aNode.setDestination(((SVGAElement)e).getHref().getBaseVal()); + aNode.setTransform(transform); + return aNode; + } + + /** + * Returns true as the <a> element is a container. + * @return true if the a element is a container + */ + public boolean isComposite() { + return true; + } + +} diff --git a/src/java/org/apache/fop/svg/PDFANode.java b/src/java/org/apache/fop/svg/PDFANode.java new file mode 100644 index 000000000..a200da27d --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFANode.java @@ -0,0 +1,156 @@ +/* + * $Id: PDFANode.java,v 1.11 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.batik.gvt.CompositeGraphicsNode; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.geom.AffineTransform; + +import java.util.StringTokenizer; + +/** + * A graphics node that represents an image described as a graphics node. + * + * @author Keiron Liddle + */ +public class PDFANode extends CompositeGraphicsNode { + private String destination; + private AffineTransform transform; + + /** + * Constructs a new empty PDFANode. + */ + public PDFANode() { + } + + /** + * Set the destination String. + * @param dest the target destination + */ + public void setDestination(String dest) { + destination = dest; + } + + /** + * Set the current transform of this node. + * @param tf the transform + */ + public void setTransform(AffineTransform tf) { + transform = tf; + } + + /** + * Paints this node if visible. + * + * @param g2d the Graphics2D to use + */ + public void paint(Graphics2D g2d) { + if (isVisible) { + super.paint(g2d); + if (g2d instanceof PDFGraphics2D) { + PDFGraphics2D pdfg = (PDFGraphics2D)g2d; + int type = org.apache.fop.pdf.PDFLink.EXTERNAL; + Shape outline = getOutline(); + if (destination.startsWith("#svgView(viewBox(")) { + type = org.apache.fop.pdf.PDFLink.INTERNAL; + String nums = destination.substring(17, destination.length() - 2); + float x = 0; + float y = 0; + float width = 0; + float height = 0; + int count = 0; + try { + StringTokenizer st = new StringTokenizer(nums, ","); + while (st.hasMoreTokens()) { + String tok = st.nextToken(); + count++; + switch(count) { + case 1: + x = Float.parseFloat(tok); + break; + case 2: + y = Float.parseFloat(tok); + break; + case 3: + width = Float.parseFloat(tok); + break; + case 4: + height = Float.parseFloat(tok); + break; + default: + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Rectangle2D destRect = new Rectangle2D.Float(x, y, width, height); + destRect = transform.createTransformedShape(destRect).getBounds(); + // these numbers need conversion to current + // svg position and scaled for the page + x = (float)destRect.getX(); + y = (float)destRect.getY(); + width = (float)destRect.getWidth(); + height = (float)destRect.getHeight(); + + destination = "" + x + " " + y + " " + + (x + width) + " " + (y + height); + } + pdfg.addLink(getBounds(), transform, destination, type); + } + } + } + +} + diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java new file mode 100644 index 000000000..0ac52f075 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -0,0 +1,279 @@ +/* + * $Id: PDFDocumentGraphics2D.java,v 1.27 2003/03/07 09:51:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFStream; +import org.apache.fop.pdf.PDFState; +import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFResources; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.PDFAnnotList; +import org.apache.fop.render.pdf.FontSetup; +import org.apache.fop.layout.FontInfo; + +import java.awt.Graphics; +import java.awt.Font; +import java.awt.Color; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.io.OutputStream; +import java.io.IOException; + +/** + * This class is a wrapper for the PDFGraphics2D that + * is used to create a full document around the pdf rendering from + * PDFGraphics2D. + * + * @author Keiron Liddle + * @version $Id: PDFDocumentGraphics2D.java,v 1.27 2003/03/07 09:51:26 jeremias Exp $ + * @see org.apache.fop.svg.PDFGraphics2D + */ +public class PDFDocumentGraphics2D extends PDFGraphics2D { + private PDFPage currentPage; + private PDFStream pdfStream; + private int width; + private int height; + + /** + * Create a new PDFDocumentGraphics2D. + * This is used to create a new pdf document, the height, + * width and output stream can be setup later. + * For use by the transcoder which needs font information + * for the bridge before the document size is known. + * The resulting document is written to the stream after rendering. + * + * @param textAsShapes set this to true so that text will be rendered + * using curves and not the font. + */ + PDFDocumentGraphics2D(boolean textAsShapes) { + super(textAsShapes); + + if (!textAsShapes) { + fontInfo = new FontInfo(); + FontSetup.setup(fontInfo, null); + //FontState fontState = new FontState("Helvetica", "normal", + // FontInfo.NORMAL, 12, 0); + } + + this.pdfDoc = new PDFDocument("FOP SVG Renderer"); + + graphicsState = new PDFState(); + + currentFontName = ""; + currentFontSize = 0; + + pdfStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER, false); + } + + /** + * Setup the document. + * @param stream the output stream to write the document + * @param width the width of the page + * @param height the height of the page + * @throws IOException an io exception if there is a problem + * writing to the output stream + */ + public void setupDocument(OutputStream stream, int width, int height) throws IOException { + this.width = width; + this.height = height; + + PDFResources pdfResources = this.pdfDoc.getResources(); + currentPage = this.pdfDoc.makePage(pdfResources, + width, height); + resourceContext = currentPage; + pageRef = currentPage.referencePDF(); + currentStream.write("1 0 0 -1 0 " + height + " cm\n"); + graphicsState.setTransform(new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, (double)height)); + pdfDoc.outputHeader(stream); + + setOutputStream(stream); + } + + /** + * Create a new PDFDocumentGraphics2D. + * This is used to create a new pdf document of the given height + * and width. + * The resulting document is written to the stream after rendering. + * + * @param textAsShapes set this to true so that text will be rendered + * using curves and not the font. + * @param stream the stream that the final document should be written to. + * @param width the width of the document + * @param height the height of the document + * @throws IOException an io exception if there is a problem + * writing to the output stream + */ + public PDFDocumentGraphics2D(boolean textAsShapes, OutputStream stream, + int width, int height) throws IOException { + this(textAsShapes); + setupDocument(stream, width, height); + } + + /** + * Get the font info for this pdf document. + * @return the font information + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + /** + * Get the pdf document created by this class. + * @return the pdf document + */ + public PDFDocument getPDFDocument() { + return this.pdfDoc; + } + + /** + * Set the dimensions of the svg document that will be drawn. + * This is useful if the dimensions of the svg document are different + * from the pdf document that is to be created. + * The result is scaled so that the svg fits correctly inside the + * pdf document. + * @param w the width of the page + * @param h the height of the page + */ + public void setSVGDimension(float w, float h) { + currentStream.write("" + PDFNumber.doubleOut(width / w) + " 0 0 " + + PDFNumber.doubleOut(height / h) + " 0 0 cm\n"); + } + + /** + * Set the background of the pdf document. + * This is used to set the background for the pdf document + * Rather than leaving it as the default white. + * @param col the background colour to fill + */ + public void setBackgroundColor(Color col) { + Color c = col; + PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(), c.getBlue()); + currentStream.write("q\n"); + currentStream.write(currentColour.getColorSpaceOut(true)); + + currentStream.write("0 0 " + width + " " + height + " re\n"); + + currentStream.write("f\n"); + currentStream.write("Q\n"); + } + + /** + * The rendering process has finished. + * This should be called after the rendering has completed as there is + * no other indication it is complete. + * This will then write the results to the output stream. + * @throws IOException an io exception if there is a problem + * writing to the output stream + */ + public void finish() throws IOException { + // restorePDFState(); + + pdfStream.add(getString()); + this.pdfDoc.addStream(pdfStream); + currentPage.setContents(pdfStream); + PDFAnnotList annots = currentPage.getAnnotations(); + if (annots != null) { + this.pdfDoc.addAnnotList(annots); + } + this.pdfDoc.addPage(currentPage); + if (fontInfo != null) { + FontSetup.addToResources(pdfDoc, pdfDoc.getResources(), fontInfo); + } + this.pdfDoc.output(outputStream); + pdfDoc.outputTrailer(outputStream); + + outputStream.flush(); + } + + /** + * This constructor supports the create method + * @param g the pdf document graphics to make a copy of + */ + public PDFDocumentGraphics2D(PDFDocumentGraphics2D g) { + super(g); + } + + /** + * Creates a new Graphics object that is + * a copy of this Graphics object. + * @return a new graphics context that is a copy of + * this graphics context. + */ + public Graphics create() { + return new PDFDocumentGraphics2D(this); + } + + /** + * Draw a string to the pdf document. + * This either draws the string directly or if drawing text as + * shapes it converts the string into shapes and draws that. + * @param s the string to draw + * @param x the x position + * @param y the y position + */ + public void drawString(String s, float x, float y) { + if (super.textAsShapes) { + Font font = super.getFont(); + FontRenderContext frc = super.getFontRenderContext(); + GlyphVector gv = font.createGlyphVector(frc, s); + Shape glyphOutline = gv.getOutline(x, y); + super.fill(glyphOutline); + } else { + super.drawString(s, x, y); + } + } + +} + diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java new file mode 100644 index 000000000..64fbdcfe9 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -0,0 +1,1660 @@ +/* + * $Id: PDFGraphics2D.java,v 1.48 2003/03/07 09:51:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.fop.pdf.PDFResourceContext; +import org.apache.fop.pdf.PDFResources; +import org.apache.fop.pdf.PDFGState; +import org.apache.fop.pdf.PDFColorSpace; +import org.apache.fop.pdf.PDFColor; +import org.apache.fop.pdf.PDFState; +import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFXObject; +import org.apache.fop.pdf.PDFPattern; +import org.apache.fop.pdf.PDFDocument; +import org.apache.fop.pdf.PDFLink; +import org.apache.fop.pdf.PDFAnnotList; +import org.apache.fop.pdf.BitmapImage; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; +import org.apache.fop.render.pdf.FontSetup; +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.fonts.LazyFont; +import org.apache.fop.image.JpegImage; +import org.apache.fop.fonts.CIDFont; +import org.apache.fop.render.pdf.FopPDFImage; + +import org.apache.batik.ext.awt.g2d.AbstractGraphics2D; +import org.apache.batik.ext.awt.g2d.GraphicContext; +//import org.apache.batik.ext.awt.MultipleGradientPaint; +import org.apache.batik.ext.awt.RadialGradientPaint; +import org.apache.batik.ext.awt.LinearGradientPaint; +import org.apache.batik.gvt.PatternPaint; +import org.apache.batik.gvt.GraphicsNode; + +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.Font; +import java.awt.Image; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.Dimension; +import java.awt.BasicStroke; +import java.awt.AlphaComposite; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.ImageObserver; +import java.awt.image.RenderedImage; +import java.awt.image.Raster; +import java.awt.image.renderable.RenderableImage; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.color.ColorSpace; +import java.io.StringWriter; +import java.io.IOException; +import java.io.OutputStream; + +import java.util.Map; +import java.util.List; + +/** + * PDF Graphics 2D. + * Used for drawing into a pdf document as if it is a graphics object. + * This takes a pdf document and draws into it. + * + * @author Keiron Liddle + * @version $Id: PDFGraphics2D.java,v 1.48 2003/03/07 09:51:26 jeremias Exp $ + * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D + */ +public class PDFGraphics2D extends AbstractGraphics2D { + /** + * the PDF Document being created + */ + protected PDFDocument pdfDoc; + + /** + * The current resource context for adding fonts, patterns etc. + */ + protected PDFResourceContext resourceContext; + + /** + * The PDF reference of the current page. + */ + protected String pageRef; + + /** + * the current state of the pdf graphics + */ + protected PDFState graphicsState; + + /** + * The PDF graphics state level that this svg is being drawn into. + */ + protected int baseLevel = 0; + + /** + * The current font information. + */ + protected FontInfo fontInfo; + + /** + * The override font state used when drawing text and the font cannot be + * set using java fonts. + */ + protected FontState ovFontState = null; + + /** + * the current stream to add PDF commands to + */ + protected StringWriter currentStream = new StringWriter(); + + /** + * the current (internal) font name + */ + protected String currentFontName; + + /** + * the current font size in millipoints + */ + protected float currentFontSize; + + /** + * The output stream for the pdf document. + * If this is set then it can progressively output + * the pdf document objects to reduce memory. + * Especially with images. + */ + protected OutputStream outputStream = null; + + /** + * Create a new PDFGraphics2D with the given pdf document info. + * This is used to create a Graphics object for use inside an already + * existing document. + * + * @param textAsShapes if true then draw text as shapes + * @param fi the current font information + * @param doc the pdf document for creating pdf objects + * @param page the current resource context or page + * @param pref the PDF reference of the current page + * @param font the current font name + * @param size the current font size + */ + public PDFGraphics2D(boolean textAsShapes, FontInfo fi, PDFDocument doc, + PDFResourceContext page, String pref, String font, float size) { + super(textAsShapes); + pdfDoc = doc; + resourceContext = page; + currentFontName = font; + currentFontSize = size; + fontInfo = fi; + pageRef = pref; + graphicsState = new PDFState(); + } + + /** + * Create a new PDFGraphics2D. + * + * @param textAsShapes true if drawing text as shapes + */ + protected PDFGraphics2D(boolean textAsShapes) { + super(textAsShapes); + } + + /** + * Set the PDF state to use when starting to draw + * into the PDF graphics. + * + * @param state the PDF state + */ + public void setPDFState(PDFState state) { + graphicsState = state; + baseLevel = graphicsState.getStackLevel(); + } + + /** + * Set the output stream that this PDF document is + * being drawn to. This is so that it can progressively + * use the PDF document to output data such as images. + * This results in a significant saving on memory. + * + * @param os the output stream that is being used for the PDF document + */ + public void setOutputStream(OutputStream os) { + outputStream = os; + } + + /** + * Get the string containing all the commands written into this + * Grpahics. + * @return the string containing the PDF markup + */ + public String getString() { + return currentStream.toString(); + } + + /** + * Set the Grpahics context. + * @param c the graphics context to use + */ + public void setGraphicContext(GraphicContext c) { + gc = c; + } + + /** + * Set the override font state for drawing text. + * This is used by the PDF text painter so that it can temporarily + * set the font state when a java font cannot be used. + * The next drawString will use this font state. + * + * @param infont the font state to use + */ + public void setOverrideFontState(FontState infont) { + ovFontState = infont; + } + + /** + * This constructor supports the create method. + * This is not implemented properly. + * + * @param g the PDF graphics to make a copy of + */ + public PDFGraphics2D(PDFGraphics2D g) { + super(g); + } + + /** + * Creates a new Graphics object that is + * a copy of this Graphics object. + * @return a new graphics context that is a copy of + * this graphics context. + */ + public Graphics create() { + return new PDFGraphics2D(this); + } + + /** + * Restore the PDF graphics state to the starting state level. + */ + public void restorePDFState() { + for (int count = graphicsState.getStackLevel(); count > baseLevel; count--) { + currentStream.write("Q\n"); + } + graphicsState.restoreLevel(baseLevel); + } + + /** + * This is a pdf specific method used to add a link to the + * pdf document. + * + * @param bounds the bounds of the link in user coordinates + * @param trans the transform of the current drawing position + * @param dest the PDF destination + * @param linkType the type of link, internal or external + */ + public void addLink(Rectangle2D bounds, AffineTransform trans, String dest, int linkType) { + AffineTransform at = getTransform(); + Shape b = at.createTransformedShape(bounds); + b = trans.createTransformedShape(b); + Rectangle rect = b.getBounds(); + + if (linkType != PDFLink.EXTERNAL) { + String pdfdest = "/FitR " + dest; + resourceContext.addAnnotation(pdfDoc.makeLink(rect, pageRef, pdfdest)); + } else { + resourceContext.addAnnotation(pdfDoc.makeLink(rect, + dest, linkType, 0)); + } + } + + /** + * Add a JPEG image directly to the PDF document. + * This is used by the PDFImageElementBridge to draw a JPEG + * directly into the pdf document rather than converting the image into + * a bitmap and increasing the size. + * + * @param jpeg the jpeg image to draw + * @param x the x position + * @param y the y position + * @param width the width to draw the image + * @param height the height to draw the image + */ + public void addJpegImage(JpegImage jpeg, float x, float y, float width, float height) { + FopPDFImage fopimage = new FopPDFImage(jpeg, ""); + int xObjectNum = this.pdfDoc.addImage(resourceContext, fopimage).getXNumber(); + + AffineTransform at = getTransform(); + double[] matrix = new double[6]; + at.getMatrix(matrix); + currentStream.write("q\n"); + Shape imclip = getClip(); + writeClip(imclip); + if (!at.isIdentity()) { + currentStream.write("" + matrix[0] + " " + matrix[1] + " " + + matrix[2] + " " + matrix[3] + " " + + matrix[4] + " " + matrix[5] + " cm\n"); + } + + currentStream.write("" + width + " 0 0 " + + (-height) + " " + + x + " " + + (y + height) + " cm\n" + "/Im" + + xObjectNum + " Do\nQ\n"); + + if (outputStream != null) { + try { + this.pdfDoc.output(outputStream); + } catch (IOException ioe) { + // ignore exception, will be thrown again later + } + } + } + + /** + * Draws as much of the specified image as is currently available. + * The image is drawn with its top-left corner at + * (xy) in this graphics context's coordinate + * space. Transparent pixels in the image do not affect whatever + * pixels are already there. + *

+ * This method returns immediately in all cases, even if the + * complete image has not yet been loaded, and it has not been dithered + * and converted for the current output device. + *

+ * If the image has not yet been completely loaded, then + * drawImage returns false. As more of + * the image becomes available, the process that draws the image notifies + * the specified image observer. + * @param img the specified image to be drawn. + * @param x the x coordinate. + * @param y the y coordinate. + * @param observer object to be notified as more of + * the image is converted. + * @return true if the image was drawn + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, + ImageObserver observer) { + // System.err.println("drawImage:x, y"); + + int width = img.getWidth(observer); + int height = img.getHeight(observer); + + if (width == -1 || height == -1) { + return false; + } + + // first we look to see if we've already added this image to + // the pdf document. If so, we just reuse the reference; + // otherwise we have to build a FopImage and add it to the pdf + // document + PDFXObject imageInfo = pdfDoc.getImage("TempImage:" + img.toString()); + if (imageInfo == null) { + // OK, have to build and add a PDF image + + // scale factor + final int scaleFactor = 3; + + Dimension size = new Dimension(width * scaleFactor, height * scaleFactor); + BufferedImage buf = buildBufferedImage(size); + + java.awt.Graphics2D g = buf.createGraphics(); + g.setComposite(AlphaComposite.SrcOver); + g.setBackground(new Color(1, 1, 1, 0)); + g.setPaint(new Color(1, 1, 1, 0)); + g.fillRect(0, 0, width * scaleFactor, height * scaleFactor); + g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); + + if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) { + return false; + } + g.dispose(); + + final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3]; + byte[] mask = new byte[buf.getWidth() * buf.getHeight()]; + boolean hasMask = false; + //boolean binaryMask = true; + + Raster raster = buf.getData(); + DataBuffer bd = raster.getDataBuffer(); + + int count = 0; + int maskpos = 0; + int[] iarray; + int i, j, val, alpha, add, mult; + switch (bd.getDataType()) { + case DataBuffer.TYPE_INT: + int[][] idata = ((DataBufferInt)bd).getBankData(); + for (i = 0; i < idata.length; i++) { + iarray = idata[i]; + for (j = 0; j < iarray.length; j++) { + val = iarray[j]; + alpha = val >>> 24; + mask[maskpos++] = (byte)(alpha & 0xFF); + if (alpha != 255) { + hasMask = true; + /* + if (alpha != 0) { + binaryMask = false; + }*/ + + // System.out.println("Alpha: " + alpha); + // Composite with opaque white... + add = (255 - alpha); + mult = (alpha << 16) / 255; + result[count++] = + (byte)(add + + ((((val >> 16) & 0xFF) * mult) >> 16)); + result[count++] = + (byte)(add + + ((((val >> 8) & 0xFF) * mult) >> 16)); + result[count++] = (byte)(add + + ((((val) & 0xFF) * mult) + >> 16)); + } else { + result[count++] = (byte)((val >> 16) & 0xFF); + result[count++] = (byte)((val >> 8) & 0xFF); + result[count++] = (byte)((val) & 0xFF); + } + } + } + break; + default: + // error + break; + } + String ref = null; + if (hasMask) { + // if the mask is binary then we could convert it into a bitmask + BitmapImage fopimg = new BitmapImage("TempImageMask:" + + img.toString(), buf.getWidth(), + buf.getHeight(), mask, null); + fopimg.setColorSpace(new PDFColorSpace(PDFColorSpace.DEVICE_GRAY)); + PDFXObject xobj = pdfDoc.addImage(resourceContext, fopimg); + ref = xobj.referencePDF(); + + if (outputStream != null) { + try { + this.pdfDoc.output(outputStream); + } catch (IOException ioe) { + // ignore exception, will be thrown again later + } + } + } else { + mask = null; + } + + BitmapImage fopimg = new BitmapImage("TempImage:" + + img.toString(), buf.getWidth(), + buf.getHeight(), result, ref); + fopimg.setTransparent(new PDFColor(255, 255, 255)); + imageInfo = pdfDoc.addImage(resourceContext, fopimg); + //int xObjectNum = imageInfo.getXNumber(); + + if (outputStream != null) { + try { + this.pdfDoc.output(outputStream); + } catch (IOException ioe) { + // ignore exception, will be thrown again later + } + } + } else { + resourceContext.getPDFResources().addXObject(imageInfo); + } + + // now do any transformation required and add the actual image + // placement instance + AffineTransform at = getTransform(); + double[] matrix = new double[6]; + at.getMatrix(matrix); + currentStream.write("q\n"); + Shape imclip = getClip(); + writeClip(imclip); + if (!at.isIdentity()) { + currentStream.write("" + matrix[0] + " " + matrix[1] + " " + + matrix[2] + " " + matrix[3] + " " + + matrix[4] + " " + matrix[5] + " cm\n"); + } + currentStream.write("" + width + " 0 0 " + (-height) + " " + x + + " " + (y + height) + " cm\n" + "/Im" + + imageInfo.getXNumber() + " Do\nQ\n"); + return true; + } + + private BufferedImage buildBufferedImage(Dimension size) { + return new BufferedImage(size.width, size.height, + BufferedImage.TYPE_INT_ARGB); + } + + /** + * Draws as much of the specified image as has already been scaled + * to fit inside the specified rectangle. + *

+ * The image is drawn inside the specified rectangle of this + * graphics context's coordinate space, and is scaled if + * necessary. Transparent pixels do not affect whatever pixels + * are already there. + *

+ * This method returns immediately in all cases, even if the + * entire image has not yet been scaled, dithered, and converted + * for the current output device. + * If the current output representation is not yet complete, then + * drawImage returns false. As more of + * the image becomes available, the process that draws the image notifies + * the image observer by calling its imageUpdate method. + *

+ * A scaled version of an image will not necessarily be + * available immediately just because an unscaled version of the + * image has been constructed for this output device. Each size of + * the image may be cached separately and generated from the original + * data in a separate image production sequence. + * @param img the specified image to be drawn. + * @param x the x coordinate. + * @param y the y coordinate. + * @param width the width of the rectangle. + * @param height the height of the rectangle. + * @param observer object to be notified as more of + * the image is converted. + * @return true if the image was drawn + * @see java.awt.Image + * @see java.awt.image.ImageObserver + * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) + */ + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { + System.out.println("drawImage"); + return true; + } + + /** + * Disposes of this graphics context and releases + * any system resources that it is using. + * A Graphics object cannot be used after + * disposehas been called. + *

+ * When a Java program runs, a large number of Graphics + * objects can be created within a short time frame. + * Although the finalization process of the garbage collector + * also disposes of the same system resources, it is preferable + * to manually free the associated resources by calling this + * method rather than to rely on a finalization process which + * may not run to completion for a long period of time. + *

+ * Graphics objects which are provided as arguments to the + * paint and update methods + * of components are automatically released by the system when + * those methods return. For efficiency, programmers should + * call dispose when finished using + * a Graphics object only if it was created + * directly from a component or another Graphics object. + * @see java.awt.Graphics#finalize + * @see java.awt.Component#paint + * @see java.awt.Component#update + * @see java.awt.Component#getGraphics + * @see java.awt.Graphics#create + */ + public void dispose() { + // System.out.println("dispose"); + pdfDoc = null; + fontInfo = null; + currentStream = null; + currentFontName = null; + } + + /** + * Strokes the outline of a Shape using the settings of the + * current Graphics2D context. The rendering attributes + * applied include the Clip, Transform, + * Paint, Composite and + * Stroke attributes. + * @param s the Shape to be rendered + * @see #setStroke + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #transform + * @see #setTransform + * @see #clip + * @see #setClip + * @see #setComposite + */ + public void draw(Shape s) { + // System.out.println("draw(Shape)"); + Color c; + c = getColor(); + if (c.getAlpha() == 0) { + return; + } + + AffineTransform trans = getTransform(); + double[] tranvals = new double[6]; + trans.getMatrix(tranvals); + + Shape imclip = getClip(); + boolean newClip = graphicsState.checkClip(imclip); + boolean newTransform = graphicsState.checkTransform(trans) + && !trans.isIdentity(); + + if (newClip || newTransform) { + currentStream.write("q\n"); + graphicsState.push(); + if (newClip) { + writeClip(imclip); + } + if (newTransform) { + currentStream.write(PDFNumber.doubleOut(tranvals[0], 5) + " " + + PDFNumber.doubleOut(tranvals[1], 5) + " " + + PDFNumber.doubleOut(tranvals[2], 5) + " " + + PDFNumber.doubleOut(tranvals[3], 5) + " " + + PDFNumber.doubleOut(tranvals[4], 5) + " " + + PDFNumber.doubleOut(tranvals[5], 5) + " cm\n"); + } + } + + if (c.getAlpha() != 255) { + Map vals = new java.util.HashMap(); + vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(c.getAlpha() / 255f)); + PDFGState gstate = pdfDoc.makeGState(vals, graphicsState.getGState()); + //gstate.setAlpha(c.getAlpha() / 255f, false); + resourceContext.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } + + applyColor(c, false); + + applyPaint(getPaint(), false); + applyStroke(getStroke()); + + PathIterator iter = s.getPathIterator(new AffineTransform()); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " " + + PDFNumber.doubleOut(vals[2], 5) + " " + + PDFNumber.doubleOut(vals[3], 5) + " " + + PDFNumber.doubleOut(vals[4], 5) + " " + + PDFNumber.doubleOut(vals[5], 5) + " c\n"); + break; + case PathIterator.SEG_LINETO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " l\n"); + break; + case PathIterator.SEG_MOVETO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " m\n"); + break; + case PathIterator.SEG_QUADTO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " " + + PDFNumber.doubleOut(vals[2], 5) + " " + + PDFNumber.doubleOut(vals[3], 5) + " y\n"); + break; + case PathIterator.SEG_CLOSE: + currentStream.write("h\n"); + break; + default: + break; + } + iter.next(); + } + doDrawing(false, true, false); + if (newClip || newTransform) { + currentStream.write("Q\n"); + graphicsState.pop(); + } + } + +/* + // in theory we could set the clip using these methods + // it doesn't seem to improve the file sizes much + // and makes everything more complicated + + Shape lastClip = null; + + public void clip(Shape cl) { + super.clip(cl); + Shape newClip = getClip(); + if (newClip == null || lastClip == null + || !(new Area(newClip).equals(new Area(lastClip)))) { + graphicsState.setClip(newClip); + writeClip(newClip); + } + + lastClip = newClip; + } + + public void setClip(Shape cl) { + super.setClip(cl); + Shape newClip = getClip(); + if (newClip == null || lastClip == null + || !(new Area(newClip).equals(new Area(lastClip)))) { + for (int count = graphicsState.getStackLevel(); count > baseLevel; count--) { + currentStream.write("Q\n"); + } + graphicsState.restoreLevel(baseLevel); + currentStream.write("q\n"); + graphicsState.push(); + if (newClip != null) { + graphicsState.setClip(newClip); + } + writeClip(newClip); + } + + lastClip = newClip; + } +*/ + + /** + * Set the clipping shape for future PDF drawing in the current graphics state. + * This sets creates and writes a clipping shape that will apply + * to future drawings in the current graphics state. + * + * @param s the clipping shape + */ + protected void writeClip(Shape s) { + if (s == null) { + return; + } + PathIterator iter = s.getPathIterator(getTransform()); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " " + + PDFNumber.doubleOut(vals[2]) + " " + + PDFNumber.doubleOut(vals[3]) + " " + + PDFNumber.doubleOut(vals[4]) + " " + + PDFNumber.doubleOut(vals[5]) + " c\n"); + break; + case PathIterator.SEG_LINETO: + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " l\n"); + break; + case PathIterator.SEG_MOVETO: + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " m\n"); + break; + case PathIterator.SEG_QUADTO: + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " " + + PDFNumber.doubleOut(vals[2]) + " " + + PDFNumber.doubleOut(vals[3]) + " y\n"); + break; + case PathIterator.SEG_CLOSE: + currentStream.write("h\n"); + break; + default: + break; + } + iter.next(); + } + // clip area + currentStream.write("W\n"); + currentStream.write("n\n"); + } + + /** + * Apply the java Color to PDF. + * This converts the java colour to a PDF colour and + * sets it for the next drawing. + * + * @param col the java colour + * @param fill true if the colour will be used for filling + */ + protected void applyColor(Color col, boolean fill) { + Color c = col; + if (c.getColorSpace().getType() + == ColorSpace.TYPE_RGB) { + PDFColor currentColour = new PDFColor(c.getRed(), c.getGreen(), + c.getBlue()); + currentStream.write(currentColour.getColorSpaceOut(fill)); + } else if (c.getColorSpace().getType() + == ColorSpace.TYPE_CMYK) { + float[] cComps = c.getColorComponents(new float[3]); + double[] cmyk = new double[3]; + for (int i = 0; i < 3; i++) { + // convert the float elements to doubles for pdf + cmyk[i] = cComps[i]; + } + PDFColor currentColour = new PDFColor(cmyk[0], cmyk[1], cmyk[2], cmyk[3]); + currentStream.write(currentColour.getColorSpaceOut(fill)); + } else if (c.getColorSpace().getType() + == ColorSpace.TYPE_2CLR) { + // used for black/magenta + float[] cComps = c.getColorComponents(new float[1]); + double[] blackMagenta = new double[1]; + for (int i = 0; i < 1; i++) { + blackMagenta[i] = cComps[i]; + } + //PDFColor currentColour = new PDFColor(blackMagenta[0], blackMagenta[1]); + //currentStream.write(currentColour.getColorSpaceOut(fill)); + } else { + System.err.println("Color Space not supported by PDFGraphics2D"); + } + } + + /** + * Apply the java paint to the PDF. + * This takes the java paint sets up the appropraite PDF commands + * for the drawing with that paint. + * Currently this supports the gradients and patterns from batik. + * + * @param paint the paint to convert to PDF + * @param fill true if the paint should be set for filling + */ + protected void applyPaint(Paint paint, boolean fill) { + + if (paint instanceof LinearGradientPaint) { + LinearGradientPaint gp = (LinearGradientPaint)paint; + Color[] cols = gp.getColors(); + float[] fractions = gp.getFractions(); + Point2D p1 = gp.getStartPoint(); + Point2D p2 = gp.getEndPoint(); + //MultipleGradientPaint.CycleMethodEnum cycenum = gp.getCycleMethod(); + //boolean cyclic = (cycenum == MultipleGradientPaint.REPEAT); + AffineTransform transform = graphicsState.getTransform(); + transform.concatenate(gp.getTransform()); + + p1 = transform.transform(p1, null); + p2 = transform.transform(p2, null); + + List theCoords = new java.util.ArrayList(); + theCoords.add(new Double(p1.getX())); + theCoords.add(new Double(p1.getY())); + theCoords.add(new Double(p2.getX())); + theCoords.add(new Double(p2.getY())); + + List theExtend = new java.util.ArrayList(); + theExtend.add(new Boolean(true)); + theExtend.add(new Boolean(true)); + + List theDomain = new java.util.ArrayList(); + theDomain.add(new Double(0)); + theDomain.add(new Double(1)); + + List theEncode = new java.util.ArrayList(); + theEncode.add(new Double(0)); + theEncode.add(new Double(1)); + theEncode.add(new Double(0)); + theEncode.add(new Double(1)); + + List theBounds = new java.util.ArrayList(); + + List someColors = new java.util.ArrayList(); + + for (int count = 0; count < cols.length; count++) { + Color c1 = cols[count]; + PDFColor color1 = new PDFColor(c1.getRed(), c1.getGreen(), + c1.getBlue()); + someColors.add(color1); + if (count > 0 && count < cols.length - 1) { + theBounds.add(new Double(fractions[count])); + } + } + + PDFColorSpace aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + PDFPattern myPat = pdfDoc.createGradient(resourceContext, false, aColorSpace, + someColors, theBounds, theCoords); + currentStream.write(myPat.getColorSpaceOut(fill)); + + } else if (paint instanceof RadialGradientPaint) { + RadialGradientPaint rgp = (RadialGradientPaint)paint; + + double ar = rgp.getRadius(); + Point2D ac = rgp.getCenterPoint(); + Point2D af = rgp.getFocusPoint(); + AffineTransform transform = graphicsState.getTransform(); + AffineTransform gradt = rgp.getTransform(); + transform.concatenate(gradt); + + // find largest scaling for the radius + double scale = gradt.getScaleX(); + if (gradt.getScaleY() > scale) { + scale = gradt.getScaleY(); + } + ar = ar * scale; + ac = transform.transform(ac, null); + af = transform.transform(af, null); + + List theCoords = new java.util.ArrayList(); + // the center point af must be within the circle with + // radius ar centered at ac + theCoords.add(new Double(af.getX())); + theCoords.add(new Double(af.getY())); + theCoords.add(new Double(0)); + theCoords.add(new Double(ac.getX())); // Fx + theCoords.add(new Double(ac.getY())); // Fy + theCoords.add(new Double(ar)); + + Color[] cols = rgp.getColors(); + List someColors = new java.util.ArrayList(); + for (int count = 0; count < cols.length; count++) { + Color cc = cols[count]; + someColors.add(new PDFColor(cc.getRed(), cc.getGreen(), cc.getBlue())); + } + + float[] fractions = rgp.getFractions(); + List theBounds = new java.util.ArrayList(); + for (int count = 1; count < fractions.length - 1; count++) { + float offset = fractions[count]; + theBounds.add(new Double(offset)); + } + PDFColorSpace colSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB); + PDFPattern myPat = pdfDoc.createGradient(resourceContext, true, colSpace, + someColors, theBounds, theCoords); + + currentStream.write(myPat.getColorSpaceOut(fill)); + + } else if (paint instanceof PatternPaint) { + PatternPaint pp = (PatternPaint)paint; + createPattern(pp, fill); + } + } + + private void createPattern(PatternPaint pp, boolean fill) { + Rectangle2D rect = pp.getPatternRect(); + + FontInfo fi = new FontInfo(); + FontSetup.setup(fi, null); + + PDFResources res = pdfDoc.makeResources(); + PDFResourceContext context = new PDFResourceContext(0, pdfDoc, res); + PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, fi, + pdfDoc, context, pageRef, + "", 0); + pattGraphic.gc = (GraphicContext)this.gc.clone(); + pattGraphic.gc.validateTransformStack(); + pattGraphic.setOutputStream(outputStream); + + GraphicsNode gn = pp.getGraphicsNode(); + gn.paint(pattGraphic); + + StringWriter pattStream = new StringWriter(); + pattStream.write("q\n"); + + // this makes the pattern the right way up, since + // it is outside the original transform around the + // whole svg document + pattStream.write("1 0 0 -1 0 " + (rect.getHeight() + rect.getY()) + " cm\n"); + + pattStream.write(pattGraphic.getString()); + pattStream.write("Q"); + + List bbox = new java.util.ArrayList(); + bbox.add(new Double(0)); + bbox.add(new Double(0)); + bbox.add(new Double(rect.getWidth() + rect.getX())); + bbox.add(new Double(rect.getHeight() + rect.getY())); + + List translate = new java.util.ArrayList(); + AffineTransform pattt = pp.getPatternTransform(); + pattt.translate(rect.getWidth() + rect.getX(), rect.getHeight() + rect.getY()); + double[] flatmatrix = new double[6]; + pattt.getMatrix(flatmatrix); + translate.add(new Double(flatmatrix[0])); + translate.add(new Double(flatmatrix[1])); + translate.add(new Double(flatmatrix[2])); + translate.add(new Double(flatmatrix[3])); + translate.add(new Double(flatmatrix[4])); + translate.add(new Double(flatmatrix[5])); + + FontSetup.addToResources(pdfDoc, res, fi); + + PDFPattern myPat = pdfDoc.makePattern(resourceContext, 1, res, 1, 1, bbox, + rect.getWidth(), rect.getHeight(), + translate, null, pattStream.getBuffer()); + + currentStream.write(myPat.getColorSpaceOut(fill)); + + PDFAnnotList annots = context.getAnnotations(); + if (annots != null) { + this.pdfDoc.addAnnotList(annots); + } + + if (outputStream != null) { + try { + this.pdfDoc.output(outputStream); + } catch (IOException ioe) { + // ignore exception, will be thrown again later + } + } + } + + /** + * Apply the stroke to the PDF. + * This takes the java stroke and outputs the appropriate settings + * to the PDF so that the stroke attributes are handled. + * + * @param stroke the java stroke + */ + protected void applyStroke(Stroke stroke) { + if (stroke instanceof BasicStroke) { + BasicStroke bs = (BasicStroke)stroke; + + float[] da = bs.getDashArray(); + if (da != null) { + currentStream.write("["); + for (int count = 0; count < da.length; count++) { + if (((int)da[count]) == 0) { + // the dasharray units in pdf are (whole) numbers + // in user space units, cannot be 0 + currentStream.write("1"); + } else { + currentStream.write("" + ((int)da[count])); + } + if (count < da.length - 1) { + currentStream.write(" "); + } + } + currentStream.write("] "); + float offset = bs.getDashPhase(); + currentStream.write(((int)offset) + " d\n"); + } + int ec = bs.getEndCap(); + switch (ec) { + case BasicStroke.CAP_BUTT: + currentStream.write(0 + " J\n"); + break; + case BasicStroke.CAP_ROUND: + currentStream.write(1 + " J\n"); + break; + case BasicStroke.CAP_SQUARE: + currentStream.write(2 + " J\n"); + break; + } + + int lj = bs.getLineJoin(); + switch (lj) { + case BasicStroke.JOIN_MITER: + currentStream.write(0 + " j\n"); + break; + case BasicStroke.JOIN_ROUND: + currentStream.write(1 + " j\n"); + break; + case BasicStroke.JOIN_BEVEL: + currentStream.write(2 + " j\n"); + break; + } + float lw = bs.getLineWidth(); + currentStream.write(PDFNumber.doubleOut(lw) + " w\n"); + + float ml = bs.getMiterLimit(); + currentStream.write(PDFNumber.doubleOut(ml) + " M\n"); + } + } + + /** + * Renders a {@link RenderedImage}, + * applying a transform from image + * space into user space before drawing. + * The transformation from user space into device space is done with + * the current Transform in the Graphics2D. + * The specified transformation is applied to the image before the + * transform attribute in the Graphics2D context is applied. + * The rendering attributes applied include the Clip, + * Transform, and Composite attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + * @param img the image to be rendered + * @param xform the transformation from image space into user space + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void drawRenderedImage(RenderedImage img, AffineTransform xform) { + System.out.println("drawRenderedImage"); + } + + /** + * Renders a + * {@link RenderableImage}, + * applying a transform from image space into user space before drawing. + * The transformation from user space into device space is done with + * the current Transform in the Graphics2D. + * The specified transformation is applied to the image before the + * transform attribute in the Graphics2D context is applied. + * The rendering attributes applied include the Clip, + * Transform, and Composite attributes. Note + * that no rendering is done if the specified transform is + * noninvertible. + *

+ * Rendering hints set on the Graphics2D object might + * be used in rendering the RenderableImage. + * If explicit control is required over specific hints recognized by a + * specific RenderableImage, or if knowledge of which hints + * are used is required, then a RenderedImage should be + * obtained directly from the RenderableImage + * and rendered using + * {@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. + * @param img the image to be rendered + * @param xform the transformation from image space into user space + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + * @see #drawRenderedImage + */ + public void drawRenderableImage(RenderableImage img, + AffineTransform xform) { + System.out.println("drawRenderableImage"); + } + + /** + * Renders the text specified by the specified String, + * using the current Font and Paint attributes + * in the Graphics2D context. + * The baseline of the first character is at position + * (xy) in the User Space. + * The rendering attributes applied include the Clip, + * Transform, Paint, Font and + * Composite attributes. For characters in script systems + * such as Hebrew and Arabic, the glyphs can be rendered from right to + * left, in which case the coordinate supplied is the location of the + * leftmost character on the baseline. + * @param s the String to be rendered + * @param x the coordinate where the String + * should be rendered + * @param y the coordinate where the String + * should be rendered + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see java.awt.Graphics#setFont + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(String s, float x, float y) { + // System.out.println("drawString(String)"); + + FontState fontState; + if (ovFontState == null) { + Font gFont = getFont(); + String n = gFont.getFamily(); + if (n.equals("sanserif")) { + n = "sans-serif"; + } + int siz = gFont.getSize(); + String style = gFont.isItalic() ? "italic" : "normal"; + int weight = gFont.isBold() ? FontInfo.BOLD : FontInfo.NORMAL; + String fname = fontInfo.fontLookup(n, style, weight); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + fontState = new FontState(fname, metrics, siz * 1000); + } else { + FontMetrics metrics = fontInfo.getMetricsFor(ovFontState.getFontName()); + fontState = new FontState(ovFontState.getFontName(), + metrics, ovFontState.getFontSize()); + ovFontState = null; + } + String name; + float size; + name = fontState.getFontName(); + size = (float)fontState.getFontSize() / 1000f; + + if ((!name.equals(this.currentFontName)) + || (size != this.currentFontSize)) { + this.currentFontName = name; + this.currentFontSize = size; + currentStream.write("/" + name + " " + size + " Tf\n"); + + } + + currentStream.write("q\n"); + + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + applyColor(c, true); + int salpha = c.getAlpha(); + + if (salpha != 255) { + Map vals = new java.util.HashMap(); + vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(salpha / 255f)); + PDFGState gstate = pdfDoc.makeGState(vals, graphicsState.getGState()); + resourceContext.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } + + currentStream.write("BT\n"); + + Map kerning = null; + boolean kerningAvailable = false; + + kerning = fontState.getKerning(); + if (kerning != null && !kerning.isEmpty()) { + kerningAvailable = true; + } + + // This assumes that *all* CIDFonts use a /ToUnicode mapping + boolean useMultiByte = false; + org.apache.fop.fonts.Font f = + (org.apache.fop.fonts.Font)fontInfo.getFonts().get(name); + if (f instanceof LazyFont) { + if (((LazyFont) f).getRealFont() instanceof CIDFont) { + useMultiByte = true; + } + } else if (f instanceof CIDFont) { + useMultiByte = true; + } + + // String startText = useMultiByte ? " " : ") "; + + AffineTransform trans = getTransform(); + trans.translate(x, y); + double[] vals = new double[6]; + trans.getMatrix(vals); + + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " " + + PDFNumber.doubleOut(vals[2]) + " " + + PDFNumber.doubleOut(vals[3]) + " " + + PDFNumber.doubleOut(vals[4]) + " " + + PDFNumber.doubleOut(vals[5]) + " cm\n"); + currentStream.write("1 0 0 -1 0 0 Tm [" + startText); + + int l = s.length(); + + for (int i = 0; i < l; i++) { + char ch = fontState.mapChar(s.charAt(i)); + + if (!useMultiByte) { + if (ch > 127) { + currentStream.write("\\"); + currentStream.write(Integer.toOctalString((int)ch)); + } else { + switch (ch) { + case '(': + case ')': + case '\\': + currentStream.write("\\"); + break; + } + currentStream.write(ch); + } + } else { + currentStream.write(getUnicodeString(ch)); + } + + if (kerningAvailable && (i + 1) < l) { + addKerning(currentStream, (new Integer((int)ch)), + (new Integer((int)fontState.mapChar(s.charAt(i + 1)))), + kerning, startText, endText); + } + + } + currentStream.write(endText); + + + currentStream.write("] TJ\n"); + + currentStream.write("ET\n"); + currentStream.write("Q\n"); + } + + private void addKerning(StringWriter buf, Integer ch1, Integer ch2, + Map kerning, String startText, + String endText) { + Map kernPair = (Map)kerning.get(ch1); + + if (kernPair != null) { + Integer width = (Integer)kernPair.get(ch2); + if (width != null) { + currentStream.write(endText + (-width.intValue()) + " " + startText); + } + } + } + + /** + * Convert a char to a multibyte hex representation + */ + private String getUnicodeString(char c) { + + StringBuffer buf = new StringBuffer(4); + byte[] uniBytes = null; + try { + char[] a = { + c + }; + uniBytes = new String(a).getBytes("UnicodeBigUnmarked"); + } catch (Exception e) { + // This should never fail + } + + for (int i = 0; i < uniBytes.length; i++) { + int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) + : (int)uniBytes[i]; + + String hexString = Integer.toHexString(b); + if (hexString.length() == 1) { + buf = buf.append("0" + hexString); + } else { + buf = buf.append(hexString); + } + } + + return buf.toString(); + } + + /** + * Renders the text of the specified iterator, using the + * Graphics2D context's current Paint. The + * iterator must specify a font + * for each character. The baseline of the + * first character is at position (xy) in the + * User Space. + * The rendering attributes applied include the Clip, + * Transform, Paint, and + * Composite attributes. + * For characters in script systems such as Hebrew and Arabic, + * the glyphs can be rendered from right to left, in which case the + * coordinate supplied is the location of the leftmost character + * on the baseline. + * @param iterator the iterator whose text is to be rendered + * @param x the coordinate where the iterator's text is to be + * rendered + * @param y the coordinate where the iterator's text is to be + * rendered + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #setTransform + * @see #setComposite + * @see #setClip + */ + public void drawString(AttributedCharacterIterator iterator, float x, + float y) { + System.err.println("drawString(AttributedCharacterIterator)"); + + FontState fontState = null; + + Shape imclip = getClip(); + writeClip(imclip); + Color c = getColor(); + applyColor(c, true); + + boolean fill = true; + boolean stroke = false; + if (true) { + Stroke currentStroke = getStroke(); + stroke = true; + applyStroke(currentStroke); + applyColor(c, false); + } + + currentStream.write("BT\n"); + + // set text rendering mode: + // 0 - fill, 1 - stroke, 2 - fill then stroke + int textr = 0; + if (fill && stroke) { + textr = 2; + } else if (stroke) { + textr = 1; + } + currentStream.write(textr + " Tr\n"); + + AffineTransform trans = getTransform(); + trans.translate(x, y); + double[] vals = new double[6]; + trans.getMatrix(vals); + + for (char ch = iterator.first(); ch != CharacterIterator.DONE; + ch = iterator.next()) { + //Map attr = iterator.getAttributes(); + + String name = fontState.getFontName(); + int size = fontState.getFontSize(); + if ((!name.equals(this.currentFontName)) + || (size != this.currentFontSize)) { + this.currentFontName = name; + this.currentFontSize = size; + currentStream.write("/" + name + " " + (size / 1000) + + " Tf\n"); + + } + + currentStream.write(PDFNumber.doubleOut(vals[0]) + " " + + PDFNumber.doubleOut(vals[1]) + " " + + PDFNumber.doubleOut(vals[2]) + " " + + PDFNumber.doubleOut(vals[3]) + " " + + PDFNumber.doubleOut(vals[4]) + " " + + PDFNumber.doubleOut(vals[5]) + " Tm (" + ch + + ") Tj\n"); + } + + currentStream.write("ET\n"); + } + + /** + * Fills the interior of a Shape using the settings of the + * Graphics2D context. The rendering attributes applied + * include the Clip, Transform, + * Paint, and Composite. + * @param s the Shape to be filled + * @see #setPaint + * @see java.awt.Graphics#setColor + * @see #transform + * @see #setTransform + * @see #setComposite + * @see #clip + * @see #setClip + */ + public void fill(Shape s) { + // System.err.println("fill"); + Color c; + c = getBackground(); + if (c.getAlpha() == 0) { + c = getColor(); + if (c.getAlpha() == 0) { + return; + } + } + Shape imclip = getClip(); + boolean newState = graphicsState.checkClip(imclip); + + if (newState) { + currentStream.write("q\n"); + graphicsState.push(); + writeClip(imclip); + graphicsState.setClip(imclip); + } + + if (c.getAlpha() != 255) { + Map vals = new java.util.HashMap(); + vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(c.getAlpha() / 255f)); + PDFGState gstate = pdfDoc.makeGState(vals, graphicsState.getGState()); + resourceContext.addGState(gstate); + currentStream.write("/" + gstate.getName() + " gs\n"); + } + + c = getColor(); + if (graphicsState.setColor(c)) { + applyColor(c, true); + } + c = getBackground(); + if (graphicsState.setBackColor(c)) { + applyColor(c, false); + } + + Paint paint = getPaint(); + if (graphicsState.setPaint(paint)) { + applyPaint(paint, true); + } + + PathIterator iter = s.getPathIterator(getTransform()); + while (!iter.isDone()) { + double vals[] = new double[6]; + int type = iter.currentSegment(vals); + switch (type) { + case PathIterator.SEG_CUBICTO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " " + + PDFNumber.doubleOut(vals[2], 5) + " " + + PDFNumber.doubleOut(vals[3], 5) + " " + + PDFNumber.doubleOut(vals[4], 5) + " " + + PDFNumber.doubleOut(vals[5], 5) + " c\n"); + break; + case PathIterator.SEG_LINETO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " l\n"); + break; + case PathIterator.SEG_MOVETO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " m\n"); + break; + case PathIterator.SEG_QUADTO: + currentStream.write(PDFNumber.doubleOut(vals[0], 5) + " " + + PDFNumber.doubleOut(vals[1], 5) + " " + + PDFNumber.doubleOut(vals[2], 5) + " " + + PDFNumber.doubleOut(vals[3], 5) + " y\n"); + break; + case PathIterator.SEG_CLOSE: + currentStream.write("h\n"); + break; + default: + break; + } + iter.next(); + } + doDrawing(true, false, + iter.getWindingRule() == PathIterator.WIND_EVEN_ODD); + if (newState) { + currentStream.write("Q\n"); + graphicsState.pop(); + } + } + + /** + * Do the PDF drawing command. + * This does the PDF drawing command according to fill + * stroke and winding rule. + * + * @param fill true if filling the path + * @param stroke true if stroking the path + * @param nonzero true if using the non-zero winding rule + */ + protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) { + if (fill) { + if (stroke) { + if (nonzero) { + currentStream.write("B*\n"); + } else { + currentStream.write("B\n"); + } + } else { + if (nonzero) { + currentStream.write("f*\n"); + } else { + currentStream.write("f\n"); + } + } + } else { + // if (stroke) + currentStream.write("S\n"); + } + } + + /** + * Returns the device configuration associated with this + * Graphics2D. + * + * @return the PDF graphics configuration + */ + public GraphicsConfiguration getDeviceConfiguration() { + return new PDFGraphicsConfiguration(); + } + + /** + * Used to create proper font metrics + */ + private Graphics2D fmg; + + { + BufferedImage bi = new BufferedImage(1, 1, + BufferedImage.TYPE_INT_ARGB); + + fmg = bi.createGraphics(); + } + + /** + * Gets the font metrics for the specified font. + * @return the font metrics for the specified font. + * @param f the specified font + * @see java.awt.Graphics#getFont + * @see java.awt.FontMetrics + * @see java.awt.Graphics#getFontMetrics() + */ + public java.awt.FontMetrics getFontMetrics(Font f) { + return fmg.getFontMetrics(f); + } + + /** + * Sets the paint mode of this graphics context to alternate between + * this graphics context's current color and the new specified color. + * This specifies that logical pixel operations are performed in the + * XOR mode, which alternates pixels between the current color and + * a specified XOR color. + *

+ * When drawing operations are performed, pixels which are the + * current color are changed to the specified color, and vice versa. + *

+ * Pixels that are of colors other than those two colors are changed + * in an unpredictable but reversible manner; if the same figure is + * drawn twice, then all pixels are restored to their original values. + * @param c1 the XOR alternation color + */ + public void setXORMode(Color c1) { + System.out.println("setXORMode"); + } + + + /** + * Copies an area of the component by a distance specified by + * dx and dy. From the point specified + * by x and y, this method + * copies downwards and to the right. To copy an area of the + * component to the left or upwards, specify a negative value for + * dx or dy. + * If a portion of the source rectangle lies outside the bounds + * of the component, or is obscured by another window or component, + * copyArea will be unable to copy the associated + * pixels. The area that is omitted can be refreshed by calling + * the component's paint method. + * @param x the x coordinate of the source rectangle. + * @param y the y coordinate of the source rectangle. + * @param width the width of the source rectangle. + * @param height the height of the source rectangle. + * @param dx the horizontal distance to copy the pixels. + * @param dy the vertical distance to copy the pixels. + */ + public void copyArea(int x, int y, int width, int height, int dx, + int dy) { + System.out.println("copyArea"); + } + +} diff --git a/src/java/org/apache/fop/svg/PDFGraphicsConfiguration.javat b/src/java/org/apache/fop/svg/PDFGraphicsConfiguration.javat new file mode 100644 index 000000000..8b24b18c3 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFGraphicsConfiguration.javat @@ -0,0 +1,178 @@ +/* + * $Id: PDFGraphicsConfiguration.javat,v 1.2 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; +import java.awt.GraphicsDevice; +import java.awt.Transparency; +import java.awt.image.ColorModel; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; + +/** + * Our implementation of the class that returns information about + * roughly what we can handle and want to see (alpha for example). + */ +class PDFGraphicsConfiguration extends GraphicsConfiguration { + // We use this to get a good colormodel.. + private static final BufferedImage BI_WITH_ALPHA = + new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + // We use this to get a good colormodel.. + private static final BufferedImage BI_WITHOUT_ALPHA = + new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); + + /** + * Construct a buffered image with an alpha channel, unless + * transparencty is OPAQUE (no alpha at all). + * + * @param width the width of the image + * @param height the height of the image + * @param transparency the alpha value of the image + * @return the new buffered image + */ + public BufferedImage createCompatibleImage(int width, int height, + int transparency) { + if (transparency == Transparency.OPAQUE) { + return new BufferedImage(width, height, + BufferedImage.TYPE_INT_RGB); + } else { + return new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + } + } + + /** + * Construct a buffered image with an alpha channel. + * + * @param width the width of the image + * @param height the height of the image + * @return the new buffered image + */ + public BufferedImage createCompatibleImage(int width, int height) { + return new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + } + + /** + * FIXX ME: This should return the page bounds in Pts, + * I couldn't figure out how to get this for the current + * page from the PDFDocument (this still works for now, + * but it should be fixed...). + * + * @return the bounds of the PDF document page + */ + public Rectangle getBounds() { + System.out.println("getting getBounds"); + return null; + } + + /** + * Return a good default color model for this 'device'. + * @return the colour model for the configuration + */ + public ColorModel getColorModel() { + return BI_WITH_ALPHA.getColorModel(); + } + + /** + * Return a good color model given transparency + * + * @param transparency the alpha value for the colour model + * @return the colour model for the configuration + */ + public ColorModel getColorModel(int transparency) { + if (transparency == Transparency.OPAQUE) { + return BI_WITHOUT_ALPHA.getColorModel(); + } else { + return BI_WITH_ALPHA.getColorModel(); + } + } + + /** + * The default transform (1:1). + * + * @return the default transform for the configuration + */ + public AffineTransform getDefaultTransform() { + System.out.println("getting getDefaultTransform"); + return new AffineTransform(); + } + + /** + * The normalizing transform (1:1) (since we currently + * render images at 72dpi, which we might want to change + * in the future). + * + * @return the normalizing transform for the configuration + */ + public AffineTransform getNormalizingTransform() { + System.out.println("getting getNormalizingTransform"); + return new AffineTransform(2, 0, 0, 2, 0, 0); + } + + /** + * Return our dummy instance of GraphicsDevice + * + * @return the PDF graphics device + */ + public GraphicsDevice getDevice() { + return new PDFGraphicsDevice(this); + } + + // needed for compiling under jdk1.4 + @jdk14codestart@ + public java.awt.image.VolatileImage createCompatibleVolatileImage(int width, int height) { + return null; + } + @jdk14codeend@ +} + diff --git a/src/java/org/apache/fop/svg/PDFGraphicsDevice.java b/src/java/org/apache/fop/svg/PDFGraphicsDevice.java new file mode 100644 index 000000000..6a2e337a6 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFGraphicsDevice.java @@ -0,0 +1,127 @@ +/* + * $Id: PDFGraphicsDevice.java,v 1.3 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsConfigTemplate; + +/** + * This implements the GraphicsDevice interface as appropriate for + * a PDFGraphics2D. This is quite simple since we only have one + * GraphicsConfiguration for now (this might change in the future + * I suppose). + */ +class PDFGraphicsDevice extends GraphicsDevice { + + /** + * The Graphics Config that created us... + */ + protected GraphicsConfiguration gc; + + /** + * Create a new PDF graphics device. + * + * @param The gc we should reference + */ + PDFGraphicsDevice(PDFGraphicsConfiguration gc) { + this.gc = gc; + } + + /** + * Ignore template and return the only config we have + * + * @param gct the template configuration + * @return the best configuration which is the only one + */ + public GraphicsConfiguration getBestConfiguration( + GraphicsConfigTemplate gct) { + return gc; + } + + /** + * Return an array of our one GraphicsConfig + * + * @return an array containing the one graphics configuration + */ + public GraphicsConfiguration[] getConfigurations() { + return new GraphicsConfiguration[]{ gc }; + } + + /** + * Return out sole GraphicsConfig. + * + * @return the grpahics configuration that created this object + */ + public GraphicsConfiguration getDefaultConfiguration() { + return gc; + } + + /** + * Generate an IdString.. + * + * @return the ID string for this device, uses toString + */ + public String getIDstring() { + return toString(); + } + + /** + * Let the caller know that we are "a printer" + * + * @return the type which is always printer + */ + public int getType() { + return GraphicsDevice.TYPE_PRINTER; + } + +} + diff --git a/src/java/org/apache/fop/svg/PDFImageElementBridge.java b/src/java/org/apache/fop/svg/PDFImageElementBridge.java new file mode 100644 index 000000000..b5222f657 --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFImageElementBridge.java @@ -0,0 +1,181 @@ +/* + * $Id: PDFImageElementBridge.java,v 1.4 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.batik.bridge.SVGImageElementBridge; + +import org.apache.fop.image.JpegImage; + +import java.awt.Shape; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; + +import org.apache.batik.gvt.AbstractGraphicsNode; + +/** + * Bridge class for the <image> element when jpeg images. + * + * @author Keiron Liddle + */ +public class PDFImageElementBridge extends SVGImageElementBridge { + + /** + * Constructs a new bridge for the <image> element. + */ + public PDFImageElementBridge() { } + +/* + /** + * Create the raster image node. + * THis checks if it is a jpeg file and creates a jpeg node + * so the jpeg can be inserted directly into the pdf document. + * @param ctx the bridge context + * @param e the svg element for the image + * @param purl the parsed url for the image resource + * @return a new graphics node + * + protected GraphicsNode createRasterImageNode(BridgeContext ctx, + Element e, ParsedURL purl) { + + try { + JpegImage jpeg = new JpegImage(new URL(purl.toString())); + PDFFilter filter = jpeg.getPDFFilter(); + PDFJpegNode node = new PDFJpegNode(jpeg); + Rectangle2D bounds = node.getPrimitiveBounds(); + float [] vb = new float[4]; + vb[0] = 0; // x + vb[1] = 0; // y + vb[2] = (float) bounds.getWidth(); // width + vb[3] = (float) bounds.getHeight(); // height + + // handles the 'preserveAspectRatio', 'overflow' and 'clip' and sets the + // appropriate AffineTransform to the image node + initializeViewport(ctx, e, node, vb, bounds); + + return node; + } catch (Exception ex) { + } + + return super.createRasterImageNode(ctx, e, purl); + } +*/ + + /** + * A PDF jpeg node. + * This holds a jpeg image so that it can be drawn into + * the PDFGraphics2D. + */ + public static class PDFJpegNode extends AbstractGraphicsNode { + private JpegImage jpeg; + + /** + * Create a new pdf jpeg node for drawing jpeg images + * into pdf graphics. + * @param j the jpeg image + */ + public PDFJpegNode(JpegImage j) { + jpeg = j; + } + + /** + * Get the outline of this image. + * @return the outline shape which is the primitive bounds + */ + public Shape getOutline() { + return getPrimitiveBounds(); + } + + /** + * Paint this jpeg image. + * As this is used for inserting jpeg into pdf + * it adds the jpeg image to the PDFGraphics2D. + * @param g2d the graphics to draw the image on + */ + public void primitivePaint(Graphics2D g2d) { + if (g2d instanceof PDFGraphics2D) { + PDFGraphics2D pdfg = (PDFGraphics2D) g2d; + pdfg.setTransform(getTransform()); + float x = 0; + float y = 0; + try { + float width = jpeg.getWidth(); + float height = jpeg.getHeight(); + pdfg.addJpegImage(jpeg, x, y, width, height); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * Get the geometrix bounds of the image. + * @return the primitive bounds + */ + public Rectangle2D getGeometryBounds() { + return getPrimitiveBounds(); + } + + /** + * Get the primitive bounds of this bridge element. + * @return the bounds of the jpeg image + */ + public Rectangle2D getPrimitiveBounds() { + try { + return new Rectangle2D.Double(0, 0, jpeg.getWidth(), + jpeg.getHeight()); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + } + +} diff --git a/src/java/org/apache/fop/svg/PDFTextElementBridge.java b/src/java/org/apache/fop/svg/PDFTextElementBridge.java new file mode 100644 index 000000000..664324a2b --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFTextElementBridge.java @@ -0,0 +1,154 @@ +/* + * $Id: PDFTextElementBridge.java,v 1.11 2003/03/07 09:51:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.batik.gvt.TextNode; +import org.apache.batik.bridge.SVGTextElementBridge; +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.TextUtilities; +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.fop.layout.FontInfo; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Bridge class for the <text> element. + * This bridge will use the direct text painter if the text + * for the element is simple. + * + * @author Keiron Liddle + */ +public class PDFTextElementBridge extends SVGTextElementBridge { + private PDFTextPainter pdfTextPainter; + + /** + * Constructs a new bridge for the <text> element. + * @param fi the font infomration + */ + public PDFTextElementBridge(FontInfo fi) { + pdfTextPainter = new PDFTextPainter(fi); + } + + /** + * Create a text element bridge. + * This set the text painter on the node if the text is simple. + * @param ctx the bridge context + * @param e the svg element + * @return the text graphics node created by the super class + */ + public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { + GraphicsNode node = super.createGraphicsNode(ctx, e); + if (node != null && isSimple(ctx, e, node)) { + ((TextNode)node).setTextPainter(getTextPainter()); + } + return node; + } + + private PDFTextPainter getTextPainter() { + return pdfTextPainter; + } + + /** + * Check if text element contains simple text. + * This checks the children of the text element to determine + * if the text is simple. The text is simple if it can be rendered + * with basic text drawing algorithms. This means there are no + * alternate characters, the font is known and there are no effects + * applied to the text. + * + * @param ctx the bridge context + * @param element the svg text element + * @param node the graphics node + * @return true if this text is simple of false if it cannot be + * easily rendered using normal drawString on the PDFGraphics2D + */ + private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) { + // Font size, in user space units. + float fs = TextUtilities.convertFontSize(element).floatValue(); + // PDF cannot display fonts over 36pt + if (fs > 36) { + return false; + } + + Element nodeElement; + for (Node n = element.getFirstChild(); + n != null; + n = n.getNextSibling()) { + + switch (n.getNodeType()) { + case Node.ELEMENT_NODE: + + nodeElement = (Element)n; + + if (n.getLocalName().equals(SVG_TSPAN_TAG) + || n.getLocalName().equals(SVG_ALT_GLYPH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TEXT_PATH_TAG)) { + return false; + } else if (n.getLocalName().equals(SVG_TREF_TAG)) { + return false; + } + break; + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + } + } + + /*if (CSSUtilities.convertFilter(element, node, ctx) != null) { + return false; + }*/ + + return true; + } +} + diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java new file mode 100644 index 000000000..153ee5cba --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFTextPainter.java @@ -0,0 +1,434 @@ +/* + * $Id: PDFTextPainter.java,v 1.16 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.awt.Graphics2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.Font; + +import java.text.AttributedCharacterIterator; +import java.awt.font.TextAttribute; +import java.awt.Shape; +import java.awt.Paint; +import java.awt.Stroke; +import java.awt.Color; +import java.util.List; +import java.util.Iterator; + +import org.apache.batik.gvt.text.Mark; +import org.apache.batik.gvt.TextPainter; +import org.apache.batik.gvt.TextNode; +import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; +import org.apache.batik.gvt.font.GVTFontFamily; +import org.apache.batik.bridge.SVGFontFamily; +import org.apache.batik.gvt.renderer.StrokingTextPainter; + +import org.apache.fop.fonts.FontMetrics; +import org.apache.fop.layout.FontState; +import org.apache.fop.layout.FontInfo; + +/** + * Renders the attributed character iterator of a TextNode. + * This class draws the text directly into the PDFGraphics2D so that + * the text is not drawn using shapes which makes the PDF files larger. + * If the text is simple enough to draw then it sets the font and calls + * drawString. If the text is complex or the cannot be translated + * into a simple drawString the StrokingTextPainter is used instead. + * + * @todo handle underline, overline and strikethrough + * @todo use drawString(AttributedCharacterIterator iterator...) for some + * + * @author Keiron Liddle + * @version $Id: PDFTextPainter.java,v 1.16 2003/03/07 09:51:25 jeremias Exp $ + */ +public class PDFTextPainter implements TextPainter { + private FontInfo fontInfo; + + /** + * 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(); + + /** + * Create a new PDF text painter with the given font information. + * @param fi the fint info + */ + public PDFTextPainter(FontInfo fi) { + fontInfo = fi; + } + + /** + * Paints the specified attributed character iterator using the + * specified Graphics2D and context and font context. + * @param node the TextNode to paint + * @param g2d the Graphics2D to use + */ + public void paint(TextNode node, Graphics2D g2d) { + // System.out.println("PDFText paint"); + String txt = node.getText(); + Point2D loc = node.getLocation(); + + AttributedCharacterIterator aci = + node.getAttributedCharacterIterator(); + // reset position to start of char iterator + if (aci.getBeginIndex() == aci.getEndIndex()) { + return; + } + char ch = aci.first(); + if (ch == AttributedCharacterIterator.DONE) { + return; + } + TextNode.Anchor anchor; + anchor = (TextNode.Anchor) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE); + + List gvtFonts; + gvtFonts = (List) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); + Paint forg = (Paint) aci.getAttribute(TextAttribute.FOREGROUND); + Paint strokePaint; + strokePaint = (Paint) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT); + Float size = (Float) aci.getAttribute(TextAttribute.SIZE); + if (size == null) { + return; + } + Stroke stroke = (Stroke) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.STROKE); + /* + Float xpos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.X); + Float ypos = (Float) aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.Y); + */ + + Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE); + Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT); + + boolean useStrokePainter = false; + + if (forg instanceof Color) { + Color col = (Color) forg; + if (col.getAlpha() != 255) { + useStrokePainter = true; + } + g2d.setColor(col); + } + g2d.setPaint(forg); + g2d.setStroke(stroke); + + if (strokePaint != null) { + // need to draw using AttributedCharacterIterator + useStrokePainter = true; + } + + if (hasUnsupportedAttributes(aci)) { + useStrokePainter = true; + } + + // text contains unsupported information + if (useStrokePainter) { + PROXY_PAINTER.paint(node, g2d); + return; + } + + String style = ((posture != null) && (posture.floatValue() > 0.0)) + ? "italic" : "normal"; + int weight = ((taWeight != null) + && (taWeight.floatValue() > 1.0)) ? FontInfo.BOLD + : FontInfo.NORMAL; + + FontState fontState = null; + FontInfo fi = fontInfo; + boolean found = false; + String fontFamily = null; + if (gvtFonts != null) { + Iterator i = gvtFonts.iterator(); + while (i.hasNext()) { + GVTFontFamily fam = (GVTFontFamily) i.next(); + if (fam instanceof SVGFontFamily) { + PROXY_PAINTER.paint(node, g2d); + return; + } + fontFamily = fam.getFamilyName(); + if (fi.hasFont(fontFamily, style, weight)) { + String fname = fontInfo.fontLookup(fontFamily, style, + weight); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + int fsize = (int)(size.floatValue() * 1000); + fontState = new FontState(fname, metrics, fsize); + found = true; + break; + } + } + } + if (!found) { + String fname = + fontInfo.fontLookup("any", style, FontInfo.NORMAL); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + int fsize = (int)(size.floatValue() * 1000); + fontState = new FontState(fname, metrics, fsize); + } else { + if (g2d instanceof PDFGraphics2D) { + ((PDFGraphics2D) g2d).setOverrideFontState(fontState); + } + } + int fStyle = Font.PLAIN; + if (weight == FontInfo.BOLD) { + if (style.equals("italic")) { + fStyle = Font.BOLD | Font.ITALIC; + } else { + fStyle = Font.BOLD; + } + } else { + if (style.equals("italic")) { + fStyle = Font.ITALIC; + } else { + fStyle = Font.PLAIN; + } + } + Font font = new Font(fontFamily, fStyle, + (int)(fontState.getFontSize() / 1000)); + + g2d.setFont(font); + + float advance = getStringWidth(txt, fontState); + 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; + } + } + g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); + } + + private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) { + boolean hasunsupported = false; + Object letSpace = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING); + if (letSpace != null) { + hasunsupported = true; + } + + Object wordSpace = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING); + if (wordSpace != null) { + hasunsupported = true; + } + + AttributedCharacterIterator.Attribute key; + key = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE; + Object writeMod = aci.getAttribute(key); + if (!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals( + writeMod)) { + hasunsupported = true; + } + + Object vertOr = aci.getAttribute( + GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION); + if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals( + vertOr)) { + hasunsupported = true; + } + return hasunsupported; + } + + private float getStringWidth(String str, FontState fontState) { + float wordWidth = 0; + float whitespaceWidth = fontState.getWidth(fontState.mapChar(' ')); + + for (int i = 0; i < str.length(); i++) { + float charWidth; + char c = str.charAt(i); + if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) { + charWidth = fontState.getWidth(fontState.mapChar(c)); + if (charWidth <= 0) { + charWidth = whitespaceWidth; + } + } else { + charWidth = whitespaceWidth; + } + wordWidth += charWidth; + } + return wordWidth / 1000f; + } + + /** + * Get the outline shape of the text characters. + * This uses the StrokingTextPainter to get the outline + * shape since in theory it should be the same. + * + * @param node the text node + * @return the outline shape of the text characters + */ + public Shape getOutline(TextNode node) { + return PROXY_PAINTER.getOutline(node); + } + + /** + * Get the bounds. + * This uses the StrokingTextPainter to get the bounds + * since in theory it should be the same. + * + * @param node the text node + * @return the bounds of the text + */ + public Rectangle2D getBounds2D(TextNode node) { + return PROXY_PAINTER.getBounds2D(node); + } + + /** + * Get the geometry bounds. + * This uses the StrokingTextPainter to get the bounds + * since in theory it should be the same. + * @param node the text node + * @return the bounds of the text + */ + public Rectangle2D getGeometryBounds(TextNode node) { + return PROXY_PAINTER.getGeometryBounds(node); + } + + // Methods that have no purpose for PDF + + /** + * Get the mark. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @param pos the position + * @param all select all + * @return null + */ + public Mark getMark(TextNode node, int pos, boolean all) { + System.out.println("PDFText getMark"); + return null; + } + + /** + * Select at. + * This does nothing since the output is pdf and not interactive. + * @param x the x position + * @param y the y position + * @param node the text node + * @return null + */ + public Mark selectAt(double x, double y, TextNode node) { + System.out.println("PDFText selectAt"); + return null; + } + + /** + * Select to. + * This does nothing since the output is pdf and not interactive. + * @param x the x position + * @param y the y position + * @param beginMark the start mark + * @return null + */ + public Mark selectTo(double x, double y, Mark beginMark) { + System.out.println("PDFText selectTo"); + return null; + } + + /** + * Selec first. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @return null + */ + public Mark selectFirst(TextNode node) { + System.out.println("PDFText selectFirst"); + return null; + } + + /** + * Select last. + * This does nothing since the output is pdf and not interactive. + * @param node the text node + * @return null + */ + public Mark selectLast(TextNode node) { + System.out.println("PDFText selectLast"); + return null; + } + + /** + * Get selected. + * This does nothing since the output is pdf and not interactive. + * @param start the start mark + * @param finish the finish mark + * @return null + */ + public int[] getSelected(Mark start, Mark finish) { + System.out.println("PDFText getSelected"); + return null; + } + + /** + * Get the highlighted shape. + * This does nothing since the output is pdf and not interactive. + * @param beginMark the start mark + * @param endMark the end mark + * @return null + */ + public Shape getHighlightShape(Mark beginMark, Mark endMark) { + System.out.println("PDFText getHighlightShape"); + return null; + } + +} + diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java new file mode 100644 index 000000000..eb5bfb12b --- /dev/null +++ b/src/java/org/apache/fop/svg/PDFTranscoder.java @@ -0,0 +1,439 @@ +/* + * $Id: PDFTranscoder.java,v 1.24 2003/03/07 09:51:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.awt.Dimension; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; + +import java.awt.Color; + +import java.net.MalformedURLException; +import java.net.URL; + +import java.io.IOException; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.bridge.BridgeException; +import org.apache.batik.bridge.GVTBuilder; +import org.apache.batik.bridge.UserAgent; +import org.apache.batik.bridge.UserAgentAdapter; +import org.apache.batik.bridge.ViewBox; + +import org.apache.batik.dom.svg.SAXSVGDocumentFactory; +import org.apache.batik.dom.svg.SVGDOMImplementation; +import org.apache.batik.dom.svg.SVGOMDocument; +import org.apache.batik.dom.util.DocumentFactory; + +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.XMLAbstractTranscoder; +import org.apache.batik.transcoder.image.resources.Messages; + +import org.apache.batik.transcoder.image.ImageTranscoder; + +import org.apache.batik.util.SVGConstants; +import org.apache.batik.util.XMLResourceDescriptor; + +import org.apache.batik.gvt.TextPainter; +import org.apache.batik.gvt.renderer.StrokingTextPainter; + +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.svg.SVGDocument; +import org.w3c.dom.svg.SVGSVGElement; + +/** + * This class enables to transcode an input to a pdf document. + * + *

Two transcoding hints (KEY_WIDTH and + * KEY_HEIGHT) can be used to respectively specify the image + * width and the image height. If only one of these keys is specified, + * the transcoder preserves the aspect ratio of the original image. + * + *

The KEY_BACKGROUND_COLOR defines the background color + * to use for opaque image formats, or the background color that may + * be used for image formats that support alpha channel. + * + *

The KEY_AOI represents the area of interest to paint + * in device space. + * + *

Three additional transcoding hints that act on the SVG + * processor can be specified: + * + *

KEY_LANGUAGE to set the default language to use (may be + * used by a <switch> SVG element for example), + * KEY_USER_STYLESHEET_URI to fix the URI of a user + * stylesheet, and KEY_PIXEL_TO_MM to specify the pixel to + * millimeter conversion factor. + * + * @author Keiron Liddle + * @version $Id: PDFTranscoder.java,v 1.24 2003/03/07 09:51:26 jeremias Exp $ + */ +public class PDFTranscoder extends XMLAbstractTranscoder { + /* + public static final TranscodingHints.Key KEY_STROKE_TEXT = + new BooleanKey(); + */ + + /** + * The user agent dedicated to an ImageTranscoder. + */ + protected UserAgent userAgent = new ImageTranscoderUserAgent(); + + /** + * Constructs a new ImageTranscoder. + */ + public PDFTranscoder() { + hints.put(KEY_DOCUMENT_ELEMENT_NAMESPACE_URI, + SVGConstants.SVG_NAMESPACE_URI); + hints.put(KEY_DOCUMENT_ELEMENT, SVGConstants.SVG_SVG_TAG); + hints.put(KEY_DOM_IMPLEMENTATION, + SVGDOMImplementation.getDOMImplementation()); + } + + /** + * Transcodes the specified Document as an image in the specified output. + * + * @param document the document to transcode + * @param uri the uri of the document or null if any + * @param output the ouput where to transcode + * @exception TranscoderException if an error occured while transcoding + */ + protected void transcode(Document document, String uri, + TranscoderOutput output) throws TranscoderException { + + if (!(document instanceof SVGOMDocument)) { + throw new TranscoderException(Messages.formatMessage("notsvg", + null)); + } + SVGDocument svgDoc = (SVGDocument)document; + SVGSVGElement root = svgDoc.getRootElement(); + // initialize the SVG document with the appropriate context + String parserClassname = (String)hints.get(KEY_XML_PARSER_CLASSNAME); + + /*boolean stroke = true; + if (hints.containsKey(KEY_STROKE_TEXT)) { + stroke = ((Boolean)hints.get(KEY_STROKE_TEXT)).booleanValue(); + }*/ + PDFDocumentGraphics2D graphics = new PDFDocumentGraphics2D(false); + + // build the GVT tree + GVTBuilder builder = new GVTBuilder(); + BridgeContext ctx = new BridgeContext(userAgent); + TextPainter textPainter = null; + textPainter = new StrokingTextPainter(); + ctx.setTextPainter(textPainter); + + PDFTextElementBridge pdfTextElementBridge; + pdfTextElementBridge = new PDFTextElementBridge(graphics.getFontInfo()); + ctx.putBridge(pdfTextElementBridge); + + PDFAElementBridge pdfAElementBridge = new PDFAElementBridge(); + AffineTransform currentTransform = new AffineTransform(1, 0, 0, 1, 0, 0); + pdfAElementBridge.setCurrentTransform(currentTransform); + ctx.putBridge(pdfAElementBridge); + ctx.putBridge(new PDFImageElementBridge()); + GraphicsNode gvtRoot; + try { + gvtRoot = builder.build(ctx, svgDoc); + } catch (BridgeException ex) { + throw new TranscoderException(ex); + } + // get the 'width' and 'height' attributes of the SVG document + float docWidth = (float)ctx.getDocumentSize().getWidth(); + float docHeight = (float)ctx.getDocumentSize().getHeight(); + ctx = null; + builder = null; + + // compute the image's width and height according the hints + float imgWidth = -1; + if (hints.containsKey(ImageTranscoder.KEY_WIDTH)) { + imgWidth = + ((Float)hints.get(ImageTranscoder.KEY_WIDTH)).floatValue(); + } + float imgHeight = -1; + if (hints.containsKey(ImageTranscoder.KEY_HEIGHT)) { + imgHeight = + ((Float)hints.get(ImageTranscoder.KEY_HEIGHT)).floatValue(); + } + float width, height; + if (imgWidth > 0 && imgHeight > 0) { + width = imgWidth; + height = imgHeight; + } else if (imgHeight > 0) { + width = (docWidth * imgHeight) / docHeight; + height = imgHeight; + } else if (imgWidth > 0) { + width = imgWidth; + height = (docHeight * imgWidth) / docWidth; + } else { + width = docWidth; + height = docHeight; + } + // compute the preserveAspectRatio matrix + AffineTransform px; + String ref = null; + try { + ref = new URL(uri).getRef(); + } catch (MalformedURLException ex) { + // nothing to do, catched previously + } + + try { + px = ViewBox.getViewTransform(ref, root, width, height); + } catch (BridgeException ex) { + throw new TranscoderException(ex); + } + + if (px.isIdentity() && (width != docWidth || height != docHeight)) { + // The document has no viewBox, we need to resize it by hand. + // we want to keep the document size ratio + float d = Math.max(docWidth, docHeight); + float dd = Math.max(width, height); + float scale = dd / d; + px = AffineTransform.getScaleInstance(scale, scale); + } + // take the AOI into account if any + if (hints.containsKey(ImageTranscoder.KEY_AOI)) { + Rectangle2D aoi = (Rectangle2D)hints.get(ImageTranscoder.KEY_AOI); + // transform the AOI into the image's coordinate system + aoi = px.createTransformedShape(aoi).getBounds2D(); + AffineTransform mx = new AffineTransform(); + double sx = width / aoi.getWidth(); + double sy = height / aoi.getHeight(); + mx.scale(sx, sy); + double tx = -aoi.getX(); + double ty = -aoi.getY(); + mx.translate(tx, ty); + // take the AOI transformation matrix into account + // we apply first the preserveAspectRatio matrix + px.preConcatenate(mx); + } + // prepare the image to be painted + int w = (int)width; + int h = (int)height; + + try { + graphics.setupDocument(output.getOutputStream(), w, h); + } catch (IOException ex) { + throw new TranscoderException(ex); + } + graphics.setSVGDimension(docWidth, docHeight); + currentTransform.setTransform(1, 0, 0, -1, 0, height); + /*if (!stroke) { + textPainter = new PDFTextPainter(graphics.getFontInfo()); + ctx.setTextPainter(textPainter); + }*/ + + if (hints.containsKey(ImageTranscoder.KEY_BACKGROUND_COLOR)) { + graphics.setBackgroundColor((Color)hints.get(ImageTranscoder.KEY_BACKGROUND_COLOR)); + } + graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); + graphics.setTransform(px); + + gvtRoot.paint(graphics); + + try { + graphics.finish(); + } catch (IOException ex) { + throw new TranscoderException(ex); + } + } + + /** + * Creates a DocumentFactory that is used to create an SVG DOM + * tree. The specified DOM Implementation is ignored and the Batik + * SVG DOM Implementation is automatically used. + * + * @param domImpl the DOM Implementation (not used) + * @param parserClassname the XML parser classname + * @return the document factory + */ + protected DocumentFactory createDocumentFactory(DOMImplementation domImpl, + String parserClassname) { + return new SAXSVGDocumentFactory(parserClassname); + } + + // -------------------------------------------------------------------- + // UserAgent implementation + // -------------------------------------------------------------------- + + /** + * A user agent implementation for ImageTranscoder. + */ + protected class ImageTranscoderUserAgent extends UserAgentAdapter { + + /** + * Returns the default size of this user agent (400x400). + * @return the default viewport size + */ + public Dimension2D getViewportSize() { + return new Dimension(400, 400); + } + + /** + * Displays the specified error message using the ErrorHandler. + * @param message the message to display + */ + public void displayError(String message) { + try { + getErrorHandler().error(new TranscoderException(message)); + } catch (TranscoderException ex) { + throw new RuntimeException(); + } + } + + /** + * Displays the specified error using the ErrorHandler. + * @param e the exception to display + */ + public void displayError(Exception e) { + try { + getErrorHandler().error(new TranscoderException(e)); + } catch (TranscoderException ex) { + throw new RuntimeException(); + } + } + + /** + * Displays the specified message using the ErrorHandler. + * @param message the message to display + */ + public void displayMessage(String message) { + try { + getErrorHandler().warning(new TranscoderException(message)); + } catch (TranscoderException ex) { + throw new RuntimeException(); + } + } + + /** + * Returns the pixel to millimeter conversion factor specified in the + * TranscodingHints or 0.3528 if any. + * @return the pixel unit to millimeter factor + */ + public float getPixelUnitToMillimeter() { + Object key = ImageTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER; + if (getTranscodingHints().containsKey(key)) { + return ((Float)getTranscodingHints().get(key)).floatValue(); + } else { + // return 0.3528f; // 72 dpi + return 0.26458333333333333333333333333333f; // 96dpi + } + } + + /** + * Returns the user language specified in the + * TranscodingHints or "en" (english) if any. + * @return the languages for the transcoder + */ + public String getLanguages() { + Object key = ImageTranscoder.KEY_LANGUAGE; + if (getTranscodingHints().containsKey(key)) { + return (String)getTranscodingHints().get(key); + } else { + return "en"; + } + } + + /** + * Get the media for this transcoder. Which is always print. + * @return PDF media is "print" + */ + public String getMedia() { + return "print"; + } + + /** + * Returns the user stylesheet specified in the + * TranscodingHints or null if any. + * @return the user style sheet URI specified in the hints + */ + public String getUserStyleSheetURI() { + return (String)getTranscodingHints() + .get(ImageTranscoder.KEY_USER_STYLESHEET_URI); + } + + /** + * Returns the XML parser to use from the TranscodingHints. + * @return the XML parser class name + */ + public String getXMLParserClassName() { + Object key = KEY_XML_PARSER_CLASSNAME; + if (getTranscodingHints().containsKey(key)) { + return (String)getTranscodingHints().get(key); + } else { + return XMLResourceDescriptor.getXMLParserClassName(); + } + } + + /** + * Check if the XML parser is validating. + * @return true if the XML parser is validating + */ + public boolean isXMLParserValidating() { + return false; + } + + /** + * Unsupported operation. + * @return null since this is unsupported + */ + public AffineTransform getTransform() { + return null; + } + } +} diff --git a/src/java/org/apache/fop/svg/SVGElement.java b/src/java/org/apache/fop/svg/SVGElement.java new file mode 100644 index 000000000..24708d3db --- /dev/null +++ b/src/java/org/apache/fop/svg/SVGElement.java @@ -0,0 +1,314 @@ +/* + * $Id: SVGElement.java,v 1.34 2003/03/05 15:08:45 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +// FOP +import org.apache.fop.fo.FONode; +import org.apache.fop.apps.FOPException; + +import org.apache.batik.dom.svg.SVGOMDocument; +import org.apache.batik.dom.svg.SVGOMElement; +import org.apache.batik.dom.svg.SVGContext; +import org.apache.batik.dom.util.XMLSupport; +import org.w3c.dom.Element; +import org.w3c.dom.svg.SVGDocument; +import org.xml.sax.Attributes; +import org.apache.batik.bridge.UnitProcessor; +import org.apache.batik.util.SVGConstants; + +import org.w3c.dom.DOMImplementation; + +import org.apache.batik.dom.svg.SVGDOMImplementation; + +import java.net.URL; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +/** + * class representing the SVG root element + * for constructing an svg document. + */ +public class SVGElement extends SVGObj { + + /** + * Constructs an SVG object + * + * @param parent the parent formatting object + */ + public SVGElement(FONode parent) { + super(parent); + } + + /** + * Handle the xml attributes from SAX. + * @param attlist the attribute list + * @throws FOPException not thrown from here + */ + public void handleAttrs(Attributes attlist) throws FOPException { + super.handleAttrs(attlist); + init(); + } + + /** + * Get the dimensions of this XML document. + * @param view the viewport dimensions + * @return the dimensions of this SVG document + */ + public Point2D getDimension(final Point2D view) { + + // TODO - change so doesn't hold onto fo,area tree + Element svgRoot = element; + /* create an SVG area */ + /* if width and height are zero, get the bounds of the content. */ + + try { + String baseDir = userAgent.getBaseURL(); + if (baseDir != null) { + ((SVGOMDocument)doc).setURLObject(new URL(baseDir)); + } + } catch (Exception e) { + getLogger().error("Could not set base URL for svg", e); + } + + Element e = ((SVGDocument)doc).getRootElement(); + final float ptmm = userAgent.getPixelUnitToMillimeter(); + // temporary svg context + SVGContext dc = new SVGContext() { + public float getPixelToMM() { + return ptmm; + } + public float getPixelUnitToMillimeter() { + return ptmm; + } + + public Rectangle2D getBBox() { + return new Rectangle2D.Double(0, 0, view.getX(), view.getY()); + } + + /** + * Returns the transform from the global transform space to pixels. + */ + public AffineTransform getScreenTransform() { + throw new UnsupportedOperationException("NYI"); + } + + /** + * Sets the transform to be used from the global transform space + * to pixels. + */ + public void setScreenTransform(AffineTransform at) { + throw new UnsupportedOperationException("NYI"); + } + + public AffineTransform getCTM() { + return new AffineTransform(); + } + + public AffineTransform getGlobalTransform() { + return new AffineTransform(); + } + + public float getViewportWidth() { + return (float)view.getX(); + } + + public float getViewportHeight() { + return (float)view.getY(); + } + + public float getFontSize() { + return 12; + } + }; + ((SVGOMElement)e).setSVGContext(dc); + + //if (!e.hasAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns")) { + e.setAttributeNS(XMLSupport.XMLNS_NAMESPACE_URI, "xmlns", + SVGDOMImplementation.SVG_NAMESPACE_URI); + //} + int fontSize = 12; + Point2D p2d = getSize(fontSize, svgRoot, userAgent.getPixelUnitToMillimeter()); + ((SVGOMElement)e).setSVGContext(null); + + return p2d; + } + + private void init() { + DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); + String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; + doc = impl.createDocument(svgNS, "svg", null); + + element = doc.getDocumentElement(); + + buildTopLevel(doc, element); + } + + /** + * Get the size of the SVG root element. + * @param size the font size + * @param svgRoot the svg root element + * @param ptmm the pixel to millimeter conversion factor + * @return the size of the SVG document + */ + public static Point2D getSize(int size, Element svgRoot, float ptmm) { + String str; + UnitProcessor.Context ctx; + ctx = new PDFUnitContext(size, svgRoot, ptmm); + str = svgRoot.getAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE); + if (str.length() == 0) { + str = "100%"; + } + float width = UnitProcessor.svgHorizontalLengthToUserSpace + (str, SVGConstants.SVG_WIDTH_ATTRIBUTE, ctx); + + str = svgRoot.getAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE); + if (str.length() == 0) { + str = "100%"; + } + float height = UnitProcessor.svgVerticalLengthToUserSpace + (str, SVGConstants.SVG_HEIGHT_ATTRIBUTE, ctx); + return new Point2D.Float(width, height); + } + + /** + * This class is the default context for a particular + * element. Informations not available on the element are get from + * the bridge context (such as the viewport or the pixel to + * millimeter factor. + */ + public static class PDFUnitContext implements UnitProcessor.Context { + + /** The element. */ + private Element e; + private int fontSize; + private float pixeltoMM; + + /** + * Create a PDF unit context. + * @param size the font size. + * @param e the svg element + * @param ptmm the pixel to millimeter factor + */ + public PDFUnitContext(int size, Element e, float ptmm) { + this.e = e; + this.fontSize = size; + this.pixeltoMM = ptmm; + } + + /** + * Returns the element. + * @return the element + */ + public Element getElement() { + return e; + } + + /** + * Returns the context of the parent element of this context. + * Since this is always for the root SVG element there never + * should be one... + * @return null + */ + public UnitProcessor.Context getParentElementContext() { + return null; + } + + /** + * Returns the pixel to mm factor. (this is deprecated) + * @return the pixel to millimeter factor + */ + public float getPixelToMM() { + return pixeltoMM; + } + + /** + * Returns the pixel to mm factor. + * @return the pixel to millimeter factor + */ + public float getPixelUnitToMillimeter() { + return pixeltoMM; + } + + /** + * Returns the font-size value. + * @return the default font size + */ + public float getFontSize() { + return fontSize; + } + + /** + * Returns the x-height value. + * @return the x-height value + */ + public float getXHeight() { + return 0.5f; + } + + /** + * Returns the viewport width used to compute units. + * @return the default viewport width of 100 + */ + public float getViewportWidth() { + return 100; + } + + /** + * Returns the viewport height used to compute units. + * @return the default viewport height of 100 + */ + public float getViewportHeight() { + return 100; + } + } +} + diff --git a/src/java/org/apache/fop/svg/SVGElementMapping.java b/src/java/org/apache/fop/svg/SVGElementMapping.java new file mode 100644 index 000000000..dd6296cd5 --- /dev/null +++ b/src/java/org/apache/fop/svg/SVGElementMapping.java @@ -0,0 +1,115 @@ +/* + * $Id: SVGElementMapping.java,v 1.24 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.util.HashMap; + +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FOTreeBuilder; +import org.apache.fop.fo.ElementMapping; +import org.apache.fop.apps.Driver; + +import org.apache.batik.util.XMLResourceDescriptor; +import org.apache.batik.dom.svg.SVGDOMImplementation; + +/** + * Setup the SVG element mapping. + * This adds the svg element mappings used to create the objects + * that create the SVG Document. + */ +public class SVGElementMapping implements ElementMapping { + private static HashMap foObjs = null; + private static boolean batik = true; + + private static synchronized void setupSVG() { + if (foObjs == null) { + // this sets the parser that will be used + // by default (SVGBrokenLinkProvider) + // normally the user agent value is used + XMLResourceDescriptor.setXMLParserClassName( + Driver.getParserClassName()); + + foObjs = new HashMap(); + foObjs.put("svg", new SE()); + foObjs.put(DEFAULT, new SVGMaker()); + } + } + + /** + * Add the SVG element mappings to the tree builder. + * @param builder the FOTreeBuilder to add the mappings to + */ + public void addToBuilder(FOTreeBuilder builder) { + if (batik) { + try { + setupSVG(); + String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; + builder.addMapping(svgNS, foObjs); + } catch (Throwable t) { + // if the classes are not available + // the DISPLAY is not checked + batik = false; + } + } + } + + static class SVGMaker extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new SVGObj(parent); + } + } + + static class SE extends ElementMapping.Maker { + public FONode make(FONode parent) { + return new SVGElement(parent); + } + } +} diff --git a/src/java/org/apache/fop/svg/SVGObj.java b/src/java/org/apache/fop/svg/SVGObj.java new file mode 100644 index 000000000..07019acd4 --- /dev/null +++ b/src/java/org/apache/fop/svg/SVGObj.java @@ -0,0 +1,79 @@ +/* + * $Id: SVGObj.java,v 1.12 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.XMLObj; + +/** + * Class for SVG element objects. + * This aids in the construction of the SVG Document. + */ +public class SVGObj extends XMLObj { + /** + * constructs an svg object (called by Maker). + * + * @param parent the parent formatting object + */ + public SVGObj(FONode parent) { + super(parent); + } + + /** + * Get the namespace for svg. + * @return the svg namespace + */ + public String getNameSpace() { + return "http://www.w3.org/2000/svg"; + } + +} + diff --git a/src/java/org/apache/fop/svg/SVGUserAgent.java b/src/java/org/apache/fop/svg/SVGUserAgent.java new file mode 100644 index 000000000..b90609d81 --- /dev/null +++ b/src/java/org/apache/fop/svg/SVGUserAgent.java @@ -0,0 +1,184 @@ +/* + * $Id: SVGUserAgent.java,v 1.14 2003/03/07 09:51:25 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import org.apache.fop.fo.FOUserAgent; + +import org.apache.batik.bridge.UserAgentAdapter; + +import org.apache.avalon.framework.logger.Logger; + +// Java +import java.awt.geom.AffineTransform; +import java.awt.geom.Dimension2D; +import java.awt.Dimension; + +/** + * The SVG user agent. + * This is an implementation of the batik svg user agent + * for handling errors and getting user agent values. + */ +public class SVGUserAgent extends UserAgentAdapter { + private AffineTransform currentTransform = null; + private Logger log; + private FOUserAgent userAgent; + + /** + * Creates a new SVGUserAgent. + * @param ua the FO user agent + * @param at the current transform + */ + public SVGUserAgent(FOUserAgent ua, AffineTransform at) { + currentTransform = at; + userAgent = ua; + log = userAgent.getLogger(); + } + + /** + * Displays an error message. + * @param message the message to display + */ + public void displayError(String message) { + log.error(message); + } + + /** + * Displays an error resulting from the specified Exception. + * @param ex the exception to display + */ + public void displayError(Exception ex) { + log.error("SVG Error" + ex.getMessage(), ex); + } + + /** + * Displays a message in the User Agent interface. + * The given message is typically displayed in a status bar. + * @param message the message to display + */ + public void displayMessage(String message) { + log.info(message); + } + + /** + * Shows an alert dialog box. + * @param message the message to display + */ + public void showAlert(String message) { + log.warn(message); + } + + /** + * Returns a customized the pixel to mm factor. + * @return the pixel unit to millimeter conversion factor + */ + public float getPixelUnitToMillimeter() { + return userAgent.getPixelUnitToMillimeter(); + } + + /** + * Returns the language settings. + * @return the languages supported + */ + public String getLanguages() { + return "en"; // userLanguages; + } + + /** + * Returns the media type for this rendering. + * @return the media for fo documents is "print" + */ + public String getMedia() { + return "print"; + } + + /** + * Returns the user stylesheet uri. + * @return null if no user style sheet was specified. + */ + public String getUserStyleSheetURI() { + return null; // userStyleSheetURI; + } + + /** + * Returns the class name of the XML parser. + * @return the XML parser class name + */ + public String getXMLParserClassName() { + return org.apache.fop.apps.Driver.getParserClassName(); + } + + /** + * Is the XML parser validating. + * @return true if the xml parser is validating + */ + public boolean isXMLParserValidating() { + return false; + } + + /** + * Get the transform of the svg document. + * @return the transform + */ + public AffineTransform getTransform() { + return currentTransform; + } + + /** + * Get the default viewport size for an svg document. + * This returns a default value of 100x100. + * @return the default viewport size + */ + public Dimension2D getViewportSize() { + return new Dimension(100, 100); + } + +} + diff --git a/src/java/org/apache/fop/svg/SVGUtilities.java b/src/java/org/apache/fop/svg/SVGUtilities.java new file mode 100644 index 000000000..b82771c57 --- /dev/null +++ b/src/java/org/apache/fop/svg/SVGUtilities.java @@ -0,0 +1,301 @@ +/* + * $Id: SVGUtilities.java,v 1.6 2003/03/07 09:51:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.svg; + +import java.util.StringTokenizer; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.font.FontRenderContext; + +//import org.apache.fop.fo.*; +//import org.apache.fop.datatypes.*; +import org.w3c.dom.Element; +import org.w3c.dom.Document; +import org.w3c.dom.DOMImplementation; + +import org.apache.batik.dom.svg.SVGDOMImplementation; + +/** + * Some utilities for creating svg DOM documents and elements. + */ +public class SVGUtilities { + private static final String SVG_NS = SVGDOMImplementation.SVG_NAMESPACE_URI; + + /** + * Create a new svg document with batik. + * @param width the width of the root svg element + * @param height the height of the root svg element + * @return a new SVG Document + */ + public static final Document createSVGDocument(float width, + float height) { + DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); + Document doc = impl.createDocument(SVG_NS, "svg", null); + + Element svgRoot = doc.getDocumentElement(); + svgRoot.setAttributeNS(null, "width", "" + width); + svgRoot.setAttributeNS(null, "height", "" + height); + return doc; + } + + /** + * Get the string width for a particular string given the font. + * @param str the string + * @param font the font + * @return the width of the string in the given font + */ + public static final float getStringWidth(String str, java.awt.Font font) { + Rectangle2D rect = + font.getStringBounds(str, 0, str.length(), + new FontRenderContext(new AffineTransform(), + true, true)); + return (float)rect.getWidth(); + } + + /** + * Get the string height for a particular string given the font. + * @param str the string + * @param font the font + * @return the height of the string in the given font + */ + public static final float getStringHeight(String str, + java.awt.Font font) { + Rectangle2D rect = + font.getStringBounds(str, 0, str.length(), + new FontRenderContext(new AffineTransform(), + true, true)); + return (float)rect.getHeight(); + } + + /** + * Get the string bounds for a particular string given the font. + * @param str the string + * @param font the font + * @return the bounds of the string + */ + public static final Rectangle2D getStringBounds(String str, + java.awt.Font font) { + return font.getStringBounds(str, 0, str.length(), + new FontRenderContext(new AffineTransform(), + true, true)); + } + + /** + * Create an SVG Line + * @param doc the document to create the element + * @param x the start x position + * @param y the start y position + * @param x2 the end x position + * @param y2 the end y position + * @return the new line element + */ + public static final Element createLine(Document doc, float x, float y, + float x2, float y2) { + Element ellipse = doc.createElementNS(SVG_NS, "line"); + ellipse.setAttributeNS(null, "x1", "" + x); + ellipse.setAttributeNS(null, "x2", "" + x2); + ellipse.setAttributeNS(null, "y1", "" + y); + ellipse.setAttributeNS(null, "y2", "" + y2); + return ellipse; + } + + /** + * Create an SVG Ellipse + * @param doc the document to create the element + * @param cx the centre x position + * @param cy the centre y position + * @param rx the x axis radius + * @param ry the y axis radius + * @return the new ellipse element + */ + public static final Element createEllipse(Document doc, float cx, + float cy, float rx, float ry) { + Element ellipse = doc.createElementNS(SVG_NS, "ellipse"); + ellipse.setAttributeNS(null, "cx", "" + cx); + ellipse.setAttributeNS(null, "rx", "" + rx); + ellipse.setAttributeNS(null, "cy", "" + cy); + ellipse.setAttributeNS(null, "ry", "" + ry); + return ellipse; + } + + /** + * Create an SVG Path. + * @param doc the document to create the element + * @param str the string for the d attribute on the path + * @return the new path element + */ + public static final Element createPath(Document doc, String str) { + Element path = doc.createElementNS(SVG_NS, "path"); + path.setAttributeNS(null, "d", str); + return path; + } + + /** + * Create an SVG Text object. + * @param doc the document to create the element + * @param x the start x position + * @param y the start y position + * @param str the string + * @return the new text element + */ + public static final Element createText(Document doc, float x, float y, + String str) { + Element textGraph = doc.createElementNS(SVG_NS, "text"); + textGraph.setAttributeNS(null, "x", "" + x); + textGraph.setAttributeNS(null, "y", "" + y); + org.w3c.dom.Text text = doc.createTextNode(str); + textGraph.appendChild(text); + return textGraph; + } + + /** + * Create an SVG Rectangle. + * @param doc the document to create the element + * @param x the start x position + * @param y the start y position + * @param width the width of the rectangle + * @param height the height of the rectangle + * @return the new rectangle element + */ + public static final Element createRect(Document doc, float x, float y, + float width, float height) { + Element border = doc.createElementNS(SVG_NS, "rect"); + border.setAttributeNS(null, "x", "" + x); + border.setAttributeNS(null, "y", "" + y); + border.setAttributeNS(null, "width", "" + width); + border.setAttributeNS(null, "height", "" + height); + return border; + } + + /** + * Create an SVG G. + * @param doc the document to create the element + * @return the new g element + */ + public static final Element createG(Document doc) { + Element border = doc.createElementNS(SVG_NS, "g"); + return border; + } + + /** + * Create an SVG Clip. + * @param doc the document to create the element + * @param els the child elements that make the clip + * @param id the id of the clipping path + * @return the new clip element + */ + public static final Element createClip(Document doc, Element els, + String id) { + Element border = doc.createElementNS(SVG_NS, "clipPath"); + border.setAttributeNS(null, "id", id); + border.appendChild(els); + return border; + } + + /** + * Create and svg image element. + * @param doc the document to create the element + * @param ref the href link to the image + * @param width the width to set on the image + * @param height the height to set on the image + * @return a new image element + */ + public static final Element createImage(Document doc, String ref, + float width, float height) { + Element border = doc.createElementNS(SVG_NS, "image"); + border.setAttributeNS("http://www.w3.org/1999/xlink", "href", + ref); + border.setAttributeNS(null, "width", "" + width); + border.setAttributeNS(null, "height", "" + height); + return border; + } + + /** + * Create some SVG text that is wrapped into a specified width. + * @param doc the document to create the elements + * @param str the string to wrap + * @param font the font + * @param width the width to wrap + * @return the new element containing the wrapped text + */ + public static final Element wrapText(Document doc, String str, + java.awt.Font font, float width) { + Element g = createG(doc); + Element text; + StringTokenizer st = new StringTokenizer(str, " \t\r\n"); + float totalWidth = 0; + String totalStr = ""; + int line = 0; + float height = getStringHeight(str, font); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + float strwidth = getStringWidth(token, font); + totalWidth += strwidth; + if (totalWidth > width) { + if (totalStr.equals("")) { + totalStr = token; + token = ""; + strwidth = 0; + } + text = createText(doc, 0, line * (height + 5), totalStr); + g.appendChild(text); + totalStr = token; + totalWidth = strwidth; + line++; + } else { + totalStr = totalStr + " " + token; + } + } + + return g; + } + +} diff --git a/src/java/org/apache/fop/svg/package.html b/src/java/org/apache/fop/svg/package.html new file mode 100644 index 000000000..1f7cfb6be --- /dev/null +++ b/src/java/org/apache/fop/svg/package.html @@ -0,0 +1,31 @@ + +org.apache.fop.svg Package + +

Classes that add SVG support to FOP and SVG->PDF conversion for Batik.

+

+This package contains classes for drawing to PDF using +a Graphics2D implementation. +

+

+The classes: PDFAElementBridge, PDFANode, PDFImageElementBridge, +PDFTextElementBridge and PDFTextPainter are used in conjunction +with batik to draw the SVG into the PDF document. +

+

+The PDFTranscoder is a transcoder for use with batik to convert +from SVG to a single page PDF document. +

+

+SVGElement, SVGElementMapping, SVGObj and SVGUserAgent are used by +FOP for handling embedded SVG or external SVG graphics. +

+

+The PDFGraphics2D does all the work to draw into a PDF document and +the PDFDocumentGraphics2D is used when drawing into a single document. +

+

+SVGUtilities contains some useful svg element creation methods. +

+ + + diff --git a/src/java/org/apache/fop/tools/AreaTreeBuilder.java b/src/java/org/apache/fop/tools/AreaTreeBuilder.java new file mode 100644 index 000000000..c2f463dfa --- /dev/null +++ b/src/java/org/apache/fop/tools/AreaTreeBuilder.java @@ -0,0 +1,782 @@ +/* + * $Id: AreaTreeBuilder.java,v 1.16 2003/03/07 10:09:29 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools; + +// Java +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.StringTokenizer; + +// JAXP +import javax.xml.parsers.DocumentBuilderFactory; + +// DOM +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Element; +import org.w3c.dom.Document; + +// Batik +import org.apache.batik.dom.svg.SVGDOMImplementation; + +// FOP +import org.apache.fop.area.Area; +import org.apache.fop.area.AreaTree; +import org.apache.fop.area.AreaTreeModel; +import org.apache.fop.area.BeforeFloat; +import org.apache.fop.area.Block; +import org.apache.fop.area.BodyRegion; +import org.apache.fop.area.CTM; +import org.apache.fop.area.Flow; +import org.apache.fop.area.Footnote; +import org.apache.fop.area.LineArea; +import org.apache.fop.area.MainReference; +import org.apache.fop.area.Page; +import org.apache.fop.area.PageViewport; +import org.apache.fop.area.RegionReference; +import org.apache.fop.area.RegionViewport; +import org.apache.fop.area.Span; +import org.apache.fop.area.StorePagesModel; +import org.apache.fop.area.Title; +import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.Character; +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; +import org.apache.fop.area.inline.Leader; +import org.apache.fop.area.inline.Space; +import org.apache.fop.area.inline.Viewport; +import org.apache.fop.area.inline.Word; +import org.apache.fop.layout.FontInfo; +import org.apache.fop.layout.FontState; +import org.apache.fop.render.Renderer; +import org.apache.fop.render.pdf.PDFRenderer; +import org.apache.fop.render.svg.SVGRenderer; +import org.apache.fop.render.xml.XMLRenderer; +import org.apache.fop.fo.FOUserAgent; +import org.apache.fop.fo.properties.RuleStyle; +import org.apache.fop.fonts.FontMetrics; + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.AbstractLogEnabled; + + +/** + * Area tree tester. + * The purpose of this class is to create and render an area tree + * for the purpose of testing the area tree and rendering. + * This covers the set of possible properties that can be set + * on the area tree for rendering. + * As this is not for general purpose there is no attempt to handle + * invalid area tree xml. + * + * Tests: different renderers, saving and loading pages with serialization + * out of order rendering + */ +public class AreaTreeBuilder extends AbstractLogEnabled { + + /** + * Main method + * @param args command line arguments + */ + public static void main(String[] args) { + AreaTreeBuilder atb = new AreaTreeBuilder(); + atb.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG)); + + atb.runTests(args[0], args[1], args[2]); + System.exit(0); + } + + /** + * Run the tests. + * @param in input filename + * @param type output format + * @param out output filename + */ + protected void runTests(String in, String type, String out) { + getLogger().debug("Starting tests"); + runTest(in, type, out); + getLogger().debug("Finished"); + } + + /** + * Run a test. + * @param in input filename + * @param type output format + * @param out output filename + */ + protected void runTest(String in, String type, String out) { + Renderer rend = null; + if ("xml".equals(type)) { + rend = new XMLRenderer(); + } else if ("pdf".equals(type)) { + rend = new PDFRenderer(); + } else if ("svg".equals(type)) { + rend = new SVGRenderer(); + } + setupLogger(rend); + FontInfo fi = new FontInfo(); + rend.setupFontInfo(fi); + FOUserAgent ua = new FOUserAgent(); + setupLogger(ua); + rend.setUserAgent(ua); + + StorePagesModel sm = AreaTree.createStorePagesModel(); + TreeLoader tl = new TreeLoader(fi); + setupLogger(tl); + tl.setTreeModel(sm); + try { + InputStream is = + new java.io.BufferedInputStream(new java.io.FileInputStream(in)); + tl.buildAreaTree(is); + renderAreaTree(sm, rend, out); + } catch (IOException e) { + getLogger().error("error reading file" + e.getMessage(), e); + } + } + + /** + * Renders an area tree to a target format using a renderer. + * @param sm area tree pages + * @param rend renderer to use for output + * @param out target filename + */ + protected void renderAreaTree(StorePagesModel sm, + Renderer rend, String out) { + try { + OutputStream os = + new java.io.BufferedOutputStream(new java.io.FileOutputStream(out)); + + rend.startRenderer(os); + + int count = 0; + int seqc = sm.getPageSequenceCount(); + while (count < seqc) { + Title title = sm.getTitle(count); + rend.startPageSequence(title); + int pagec = sm.getPageCount(count); + int c = 0; + while (c < pagec) { + PageViewport page = sm.getPage(count, c); + c++; + // save the page to a stream for testing + /*ObjectOutputStream tempstream = new ObjectOutputStream( + new BufferedOutputStream( + new FileOutputStream("temp.ser"))); + page.savePage(tempstream); + tempstream.close(); + File temp = new File("temp.ser"); + getLogger().debug("page serialized to: " + temp.length()); + temp = null; + ObjectInputStream in = new ObjectInputStream( + new BufferedInputStream( + new FileInputStream("temp.ser"))); + page.loadPage(in); + in.close();*/ + + rend.renderPage(page); + } + count++; + } + + rend.stopRenderer(); + os.close(); + } catch (Exception e) { + getLogger().error("error rendering output", e); + } + } + + +} + +// this loads an area tree from an xml file +// the xml format is the same as the xml renderer output +class TreeLoader extends AbstractLogEnabled { + private AreaTree areaTree; + private AreaTreeModel model; + private FontInfo fontInfo; + private FontState currentFontState; + + TreeLoader(FontInfo fi) { + fontInfo = fi; + } + + public void setTreeModel(AreaTreeModel mo) { + model = mo; + } + + public void buildAreaTree(InputStream is) { + Document doc = null; + try { + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + doc = fact.newDocumentBuilder().parse(is); + } catch (Exception e) { + e.printStackTrace(); + } + Element root = null; + root = doc.getDocumentElement(); + + areaTree = new AreaTree(); + areaTree.setTreeModel(model); + + readAreaTree(root); + } + + public void readAreaTree(Element root) { + + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("pageSequence")) { + readPageSequence((Element) obj); + } + } + } + + public void readPageSequence(Element root) { + Title title = null; + boolean started = false; + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("title")) { + if (started) { + // problem + } else { + title = readTitle((Element) obj); + model.startPageSequence(title); + started = true; + } + } else if (obj.getNodeName().equals("pageViewport")) { + if (!started) { + model.startPageSequence(null); + started = true; + } + PageViewport viewport = readPageViewport((Element) obj); + areaTree.addPage(viewport); + } + } + } + + public Title readTitle(Element root) { + Title title = new Title(); + List childs = getInlineAreas(root); + for (int i = 0; i < childs.size(); i++) { + InlineArea obj = (InlineArea) childs.get(i); + title.addInlineArea(obj); + } + return title; + } + + public PageViewport readPageViewport(Element root) { + Rectangle2D bounds = getRectangle(root, "bounds"); + PageViewport viewport = null; + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("page")) { + Page page = readPage((Element) obj); + viewport = new PageViewport(page, bounds); + } + } + return viewport; + } + + public Page readPage(Element root) { + //String bounds = root.getAttribute("bounds"); + Page page = new Page(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("regionViewport")) { + readRegionViewport(page, (Element) obj); + } + } + return page; + } + + Rectangle2D getRectangle(Element root, String attr) { + String rect = root.getAttribute(attr); + StringTokenizer st = new StringTokenizer(rect, " "); + int x = 0, y = 0, w = 0, h = 0; + if (st.hasMoreTokens()) { + String tok = st.nextToken(); + x = Integer.parseInt(tok); + } + if (st.hasMoreTokens()) { + String tok = st.nextToken(); + y = Integer.parseInt(tok); + } + if (st.hasMoreTokens()) { + String tok = st.nextToken(); + w = Integer.parseInt(tok); + } + if (st.hasMoreTokens()) { + String tok = st.nextToken(); + h = Integer.parseInt(tok); + } + Rectangle2D r2d = new Rectangle2D.Float(x, y, w, h); + return r2d; + } + + public RegionViewport readRegionViewport(Page page, Element root) { + RegionViewport reg = new RegionViewport(getRectangle(root, "rect")); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("regionBefore")) { + reg.setRegion(readRegion((Element) obj, RegionReference.BEFORE)); + page.setRegion(RegionReference.BEFORE, reg); + } else if (obj.getNodeName().equals("regionStart")) { + reg.setRegion(readRegion((Element) obj, RegionReference.START)); + page.setRegion(RegionReference.START, reg); + } else if (obj.getNodeName().equals("regionBody")) { + reg.setRegion(readRegion((Element) obj, RegionReference.BODY)); + page.setRegion(RegionReference.BODY, reg); + } else if (obj.getNodeName().equals("regionEnd")) { + reg.setRegion(readRegion((Element) obj, RegionReference.END)); + page.setRegion(RegionReference.END, reg); + } else if (obj.getNodeName().equals("regionAfter")) { + reg.setRegion(readRegion((Element) obj, RegionReference.AFTER)); + page.setRegion(RegionReference.AFTER, reg); + } + } + + return reg; + } + + public RegionReference readRegion(Element root, int type) { + RegionReference reg; + if (type == RegionReference.BODY) { + BodyRegion br = new BodyRegion(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("beforeFloat")) { + BeforeFloat bf = readBeforeFloat((Element) obj); + br.setBeforeFloat(bf); + } else if (obj.getNodeName().equals("mainReference")) { + MainReference mr = readMainReference((Element) obj); + br.setMainReference(mr); + } else if (obj.getNodeName().equals("footnote")) { + Footnote foot = readFootnote((Element) obj); + br.setFootnote(foot); + } + } + reg = br; + } else { + reg = new RegionReference(type); + List blocks = getBlocks(root); + for (int i = 0; i < blocks.size(); i++) { + Block obj = (Block) blocks.get(i); + reg.addBlock(obj); + } + } + reg.setCTM(new CTM()); + return reg; + } + + public BeforeFloat readBeforeFloat(Element root) { + BeforeFloat bf = new BeforeFloat(); + List blocks = getBlocks(root); + for (int i = 0; i < blocks.size(); i++) { + Block obj = (Block) blocks.get(i); + bf.addBlock(obj); + } + return bf; + } + + public MainReference readMainReference(Element root) { + MainReference mr = new MainReference(); + List spans = getSpans(root); + for (int i = 0; i < spans.size(); i++) { + Span obj = (Span) spans.get(i); + mr.addSpan(obj); + } + return mr; + } + + List getSpans(Element root) { + List list = new java.util.ArrayList(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("span")) { + List flows = getFlows((Element) obj); + Span span = new Span(flows.size()); + for (int j = 0; j < flows.size(); j++) { + Flow flow = (Flow) flows.get(j); + span.addFlow(flow); + } + list.add(span); + } + } + return list; + } + + List getFlows(Element root) { + List list = new java.util.ArrayList(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("flow")) { + Flow flow = new Flow(); + List blocks = getBlocks((Element) obj); + for (int j = 0; j < blocks.size(); j++) { + Block block = (Block) blocks.get(j); + flow.addBlock(block); + } + list.add(flow); + } + } + return list; + } + + public Footnote readFootnote(Element root) { + Footnote foot = new Footnote(); + List blocks = getBlocks(root); + for (int i = 0; i < blocks.size(); i++) { + Block obj = (Block) blocks.get(i); + foot.addBlock(obj); + } + return foot; + } + + + List getBlocks(Element root) { + List list = new java.util.ArrayList(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("block")) { + Block block = new Block(); + addTraits((Element)obj, block); + addBlockChildren(block, (Element) obj); + list.add(block); + } + } + return list; + } + + protected void addBlockChildren(Block block, Element root) { + NodeList childs = root.getChildNodes(); + int type = -1; + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("block")) { + if (type == 2) { + // error + } + Block b = new Block(); + addBlockChildren(b, (Element) obj); + block.addBlock(b); + type = 1; + } else if (obj.getNodeName().equals("lineArea")) { + if (type == 1) { + // error + } + LineArea line = new LineArea(); + addTraits((Element) obj, line); + String height = ((Element) obj).getAttribute("height"); + int h = Integer.parseInt(height); + line.setHeight(h); + + List inlines = getInlineAreas((Element) obj); + for (int j = 0; j < inlines.size(); j++) { + InlineArea inline = (InlineArea) inlines.get(j); + line.addInlineArea(inline); + } + + block.addLineArea(line); + type = 2; + } + } + } + + // children of element are inline areas + List getInlineAreas(Element root) { + List list = new java.util.ArrayList(); + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("char")) { + Character ch = + new Character(getString((Element) obj).charAt(0)); + addTraits((Element) obj, ch); + String fname = fontInfo.fontLookup("sans-serif", "normal", FontInfo.NORMAL); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + currentFontState = + new FontState(fname, metrics, 12000); + + ch.setWidth(currentFontState.getWidth(ch.getChar())); + ch.setOffset(currentFontState.getCapHeight()); + list.add(ch); + } else if (obj.getNodeName().equals("space")) { + Space space = new Space(); + String width = ((Element) obj).getAttribute("width"); + int w = Integer.parseInt(width); + space.setWidth(w); + list.add(space); + } else if (obj.getNodeName().equals("viewport")) { + Viewport viewport = getViewport((Element) obj); + if (viewport != null) { + list.add(viewport); + } + } else if (obj.getNodeName().equals("leader")) { + Leader leader = getLeader((Element) obj); + if (leader != null) { + list.add(leader); + } + } else if (obj.getNodeName().equals("word")) { + String fname = fontInfo.fontLookup("sans-serif", "normal", FontInfo.NORMAL); + FontMetrics metrics = fontInfo.getMetricsFor(fname); + currentFontState = + new FontState(fname, metrics, 12000); + Word word = getWord((Element) obj); + + word.addTrait(Trait.FONT_NAME, fname); + word.addTrait(Trait.FONT_SIZE, new Integer(12000)); + + if (word != null) { + list.add(word); + } + } else { + } + } + return list; + } + + Viewport getViewport(Element root) { + Area child = null; + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj.getNodeName().equals("container")) { + child = getContainer((Element) obj); + } else if (obj.getNodeName().equals("foreignObject")) { + child = getForeignObject((Element) obj); + } else if (obj.getNodeName().equals("image")) { + child = getImage((Element) obj); + } + } + if (child == null) { + return null; + } + Viewport viewport = new Viewport(child); + String str = root.getAttribute("width"); + if (str != null && !"".equals(str)) { + int width = Integer.parseInt(str); + viewport.setWidth(width); + } + return viewport; + } + + Container getContainer(Element root) { + Container cont = new Container(); + List blocks = getBlocks(root); + for (int i = 0; i < blocks.size(); i++) { + Block obj = (Block) blocks.get(i); + cont.addBlock(obj); + } + return cont; + } + + ForeignObject getForeignObject(Element root) { + Document doc; + String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; + + NodeList childs = root.getChildNodes(); + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + if (obj instanceof Element) { + //getLogger().debug(obj.getNodeName()); + Element rootEle = (Element) obj; + String space = rootEle.getAttribute("xmlns"); + if (svgNS.equals(space)) { + try { + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + + doc = fact.newDocumentBuilder().newDocument(); + Node node = doc.importNode(obj, true); + doc.appendChild(node); + //DOMImplementation impl = + // SVGDOMImplementation.getDOMImplementation(); + // due to namespace problem attributes are not cloned + // serializing causes an npe + //doc = DOMUtilities.deepCloneDocument(doc, impl); + + ForeignObject fo = new ForeignObject(doc, svgNS); + return fo; + } catch (Exception e) { + e.printStackTrace(); + } + } else { + try { + DocumentBuilderFactory fact = + DocumentBuilderFactory.newInstance(); + fact.setNamespaceAware(true); + doc = fact.newDocumentBuilder().newDocument(); + Node node = doc.importNode(obj, true); + doc.appendChild(node); + ForeignObject fo = new ForeignObject(doc, space); + return fo; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return null; + } + + Image getImage(Element root) { + String url = root.getAttribute("url"); + Image image = new Image(url); + return image; + } + + Leader getLeader(Element root) { + Leader leader = new Leader(); + String rs = root.getAttribute("ruleStyle"); + if ("solid".equals(rs)) { + leader.setRuleStyle(RuleStyle.SOLID); + } else if ("dotted".equals(rs)) { + leader.setRuleStyle(RuleStyle.DOTTED); + } else if ("dashed".equals(rs)) { + leader.setRuleStyle(RuleStyle.DASHED); + } else if ("double".equals(rs)) { + leader.setRuleStyle(RuleStyle.DOUBLE); + } else if ("groove".equals(rs)) { + leader.setRuleStyle(RuleStyle.GROOVE); + } else if ("ridge".equals(rs)) { + leader.setRuleStyle(RuleStyle.RIDGE); + } + String rt = root.getAttribute("ruleThickness"); + int thick = Integer.parseInt(rt); + leader.setRuleThickness(thick); + rt = root.getAttribute("width"); + if (rt != null && !"".equals(rt)) { + thick = Integer.parseInt(rt); + leader.setWidth(thick); + } + leader.setOffset(currentFontState.getCapHeight()); + addTraits(root, leader); + return leader; + } + + Word getWord(Element root) { + String str = getString(root); + Word word = new Word(); + word.setWord(str); + addTraits(root, word); + int width = 0; + for (int count = 0; count < str.length(); count++) { + width += currentFontState.getWidth(str.charAt(count)); + } + word.setWidth(width); + word.setOffset(currentFontState.getCapHeight()); + + return word; + } + + + public void addTraits(Element ele, Area area) { + String str = ele.getAttribute("props"); + StringTokenizer st = new StringTokenizer(str, ";"); + while (st.hasMoreTokens()) { + String tok = st.nextToken(); + int index = tok.indexOf(":"); + String id = tok.substring(0, index); + Object traitCode = Trait.getTraitCode(id); + if (traitCode != null) { + area.addTrait(traitCode, + Trait.makeTraitValue(traitCode, + tok.substring(index + 1))); + } else { + getLogger().error("Unknown trait: " + id); + } + } + } + + public List getRanges(Element ele) { + List list = new java.util.ArrayList(); + String str = ele.getAttribute("ranges"); + StringTokenizer st = new StringTokenizer(str, ";"); + while (st.hasMoreTokens()) { + /*String tok =*/ st.nextToken(); + } + return list; + } + + public String getString(Element ele) { + String str = ""; + NodeList childs = ele.getChildNodes(); + if (childs.getLength() == 0) { + return null; + } + for (int i = 0; i < childs.getLength(); i++) { + Node obj = childs.item(i); + str = str + obj.getNodeValue(); + } + return str; + } + +} + diff --git a/src/java/org/apache/fop/tools/DocumentInputSource.java b/src/java/org/apache/fop/tools/DocumentInputSource.java new file mode 100644 index 000000000..c4067cc17 --- /dev/null +++ b/src/java/org/apache/fop/tools/DocumentInputSource.java @@ -0,0 +1,99 @@ +/* + * $Id: DocumentInputSource.java,v 1.4 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +/** + * This is an InputSource to be used with DocumentReader. + * + * @author Kelly A Campbell + */ +public class DocumentInputSource extends InputSource { + + private Document document; + + /** + * Default constructor. + */ + public DocumentInputSource() { + super(); + } + + /** + * Main constructor + * @param document the DOM document to use as input + */ + public DocumentInputSource(Document document) { + this(); + setDocument(document); + } + + /** + * Returns the input document. + * @return the input DOM document. + */ + public Document getDocument() { + return this.document; + } + + /** + * Sets the input document. + * @param document the DOM document to use as input + */ + public void setDocument(Document document) { + this.document = document; + } + +} + + diff --git a/src/java/org/apache/fop/tools/DocumentReader.java b/src/java/org/apache/fop/tools/DocumentReader.java new file mode 100644 index 000000000..4c0f478ea --- /dev/null +++ b/src/java/org/apache/fop/tools/DocumentReader.java @@ -0,0 +1,551 @@ +/* + * $Id: DocumentReader.java,v 1.4 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools; + +import java.io.IOException; + +// DOM +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +// SAX +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.AttributesImpl; + +/** + * This presents a DOM as an XMLReader to make it easy to use a Document + * with a SAX-based implementation. + * + * @author Kelly A Campbell + * + */ + +public class DocumentReader implements XMLReader { + + // ////////////////////////////////////////////////////////////////// + // Configuration. + // ////////////////////////////////////////////////////////////////// + private boolean namespaces = true; + private boolean namespacePrefixes = true; + + + /** + * Look up the value of a feature. + * + *

The feature name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a feature name but + * to be unable to return its value; this is especially true + * in the case of an adapter for a SAX1 Parser, which has + * no way of knowing whether the underlying parser is + * performing validation or expanding external entities.

+ * + *

All XMLReaders are required to recognize the + * http://xml.org/sax/features/namespaces and the + * http://xml.org/sax/features/namespace-prefixes feature names.

+ * + *

Some feature values may be available only in specific + * contexts, such as before, during, or after a parse.

+ * + *

Typical usage is something like this:

+ * + *
+     * XMLReader r = new MySAXDriver();
+     *
+     * // try to activate validation
+     * try {
+     * r.setFeature("http://xml.org/sax/features/validation", true);
+     * } catch (SAXException e) {
+     * System.err.println("Cannot activate validation.");
+     * }
+     *
+     * // register event handlers
+     * r.setContentHandler(new MyContentHandler());
+     * r.setErrorHandler(new MyErrorHandler());
+     *
+     * // parse the first document
+     * try {
+     * r.parse("http://www.foo.com/mydoc.xml");
+     * } catch (IOException e) {
+     * System.err.println("I/O exception reading XML document");
+     * } catch (SAXException e) {
+     * System.err.println("XML exception reading document.");
+     * }
+     * 
+ * + *

Implementors are free (and encouraged) to invent their own features, + * using names built on their own URIs.

+ * + * @param name The feature name, which is a fully-qualified URI. + * @return The current state of the feature (true or false). + * @exception SAXNotRecognizedException When the + * XMLReader does not recognize the feature name. + * @exception SAXNotSupportedException When the + * XMLReader recognizes the feature name but + * cannot determine its value at this time. + * @see #setFeature + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + if ("http://xml.org/sax/features/namespaces".equals(name)) { + return namespaces; + } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) { + return namespacePrefixes; + } else { + throw new SAXNotRecognizedException("Feature '" + name + + "' not recognized or supported by Document2SAXAdapter"); + } + + } + + + + /** + * Set the state of a feature. + * + *

The feature name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a feature name but + * to be unable to set its value; this is especially true + * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser}, + * which has no way of affecting whether the underlying parser is + * validating, for example.

+ * + *

All XMLReaders are required to support setting + * http://xml.org/sax/features/namespaces to true and + * http://xml.org/sax/features/namespace-prefixes to false.

+ * + *

Some feature values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.

+ * + * @param name The feature name, which is a fully-qualified URI. + * @param value The requested state of the feature (true or false). + * @exception SAXNotRecognizedException When the + * XMLReader does not recognize the feature name. + * @exception SAXNotSupportedException When the + * XMLReader recognizes the feature name but + * cannot set the requested value. + * @see #getFeature + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException { + if ("http://xml.org/sax/features/namespaces".equals(name)) { + namespaces = value; + } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) { + namespacePrefixes = value; + } else { + throw new SAXNotRecognizedException("Feature '" + name + + "' not recognized or supported by Document2SAXAdapter"); + } + + } + + + + /** + * Look up the value of a property. + * + *

The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * to be unable to return its state; this is especially true + * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser + * Parser}.

+ * + *

XMLReaders are not required to recognize any specific + * property names, though an initial core set is documented for + * SAX2.

+ * + *

Some property values may be available only in specific + * contexts, such as before, during, or after a parse.

+ * + *

Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.

+ * + * @param name The property name, which is a fully-qualified URI. + * @return The current value of the property. + * @exception SAXNotRecognizedException When the + * XMLReader does not recognize the property name. + * @exception SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot determine its value at this time. + * @see #setProperty + */ + public Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + throw new SAXNotRecognizedException("Property '" + name + + "' not recognized or supported by Document2SAXAdapter"); + } + + + + /** + * Set the value of a property. + * + *

The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * to be unable to set its value; this is especially true + * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser + * Parser}.

+ * + *

XMLReaders are not required to recognize setting + * any specific property names, though a core set is provided with + * SAX2.

+ * + *

Some property values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.

+ * + *

This method is also the standard mechanism for setting + * extended handlers.

+ * + * @param name The property name, which is a fully-qualified URI. + * @param value The requested value for the property. + * @exception SAXNotRecognizedException When the + * XMLReader does not recognize the property name. + * @exception SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot set the requested value. + */ + public void setProperty(String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { + throw new SAXNotRecognizedException("Property '" + name + + "' not recognized or supported by Document2SAXAdapter"); + } + + + + // ////////////////////////////////////////////////////////////////// + // Event handlers. + // ////////////////////////////////////////////////////////////////// + private EntityResolver entityResolver = null; + private DTDHandler dtdHandler = null; + private ContentHandler contentHandler = null; + private ErrorHandler errorHandler = null; + + + /** + * Allow an application to register an entity resolver. + * + *

If the application does not register an entity resolver, + * the XMLReader will perform its own default resolution.

+ * + *

Applications may register a new or different resolver in the + * middle of a parse, and the SAX parser must begin using the new + * resolver immediately.

+ * + * @param resolver The entity resolver. + * @see #getEntityResolver + */ + public void setEntityResolver(EntityResolver resolver) { + entityResolver = resolver; + } + + + + /** + * Return the current entity resolver. + * + * @return The current entity resolver, or null if none + * has been registered. + * @see #setEntityResolver + */ + public EntityResolver getEntityResolver() { + return entityResolver; + } + + + + /** + * Allow an application to register a DTD event handler. + * + *

If the application does not register a DTD handler, all DTD + * events reported by the SAX parser will be silently ignored.

+ * + *

Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler The DTD handler. + * @see #getDTDHandler + */ + public void setDTDHandler(DTDHandler handler) { + dtdHandler = handler; + } + + + + /** + * Return the current DTD handler. + * + * @return The current DTD handler, or null if none + * has been registered. + * @see #setDTDHandler + */ + public DTDHandler getDTDHandler() { + return dtdHandler; + } + + + + /** + * Allow an application to register a content event handler. + * + *

If the application does not register a content handler, all + * content events reported by the SAX parser will be silently + * ignored.

+ * + *

Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler The content handler. + * @see #getContentHandler + */ + public void setContentHandler(ContentHandler handler) { + contentHandler = handler; + } + + + + /** + * Return the current content handler. + * + * @return The current content handler, or null if none + * has been registered. + * @see #setContentHandler + */ + public ContentHandler getContentHandler() { + return contentHandler; + } + + + + /** + * Allow an application to register an error event handler. + * + *

If the application does not register an error handler, all + * error events reported by the SAX parser will be silently + * ignored; however, normal processing may not continue. It is + * highly recommended that all SAX applications implement an + * error handler to avoid unexpected bugs.

+ * + *

Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler The error handler. + * @see #getErrorHandler + */ + public void setErrorHandler(ErrorHandler handler) { + errorHandler = handler; + } + + /** + * Return the current error handler. + * + * @return The current error handler, or null if none + * has been registered. + * @see #setErrorHandler + */ + public ErrorHandler getErrorHandler() { + return errorHandler; + } + + + + // ////////////////////////////////////////////////////////////////// + // Parsing. + // ////////////////////////////////////////////////////////////////// + + /** + * Parse an XML DOM document. + * + * + * + * @param input The input source for the top-level of the + * XML document. + * @exception SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see org.xml.sax.InputSource + * @see #parse(java.lang.String) + * @see #setEntityResolver + * @see #setDTDHandler + * @see #setContentHandler + * @see #setErrorHandler + */ + public void parse(InputSource input) throws IOException, SAXException { + if (input instanceof DocumentInputSource) { + Document document = ((DocumentInputSource)input).getDocument(); + if (contentHandler == null) { + throw new SAXException("ContentHandler is null. Please use setContentHandler()"); + } + + // refactored from org.apache.fop.apps.Driver + /* most of this code is modified from John Cowan's */ + + Node currentNode; + AttributesImpl currentAtts; + + /* temporary array for making Strings into character arrays */ + char[] array = null; + + currentAtts = new AttributesImpl(); + + /* start at the document element */ + currentNode = document; + while (currentNode != null) { + switch (currentNode.getNodeType()) { + case Node.DOCUMENT_NODE: + contentHandler.startDocument(); + break; + case Node.CDATA_SECTION_NODE: + case Node.TEXT_NODE: + String data = currentNode.getNodeValue(); + int datalen = data.length(); + if (array == null || array.length < datalen) { + /* + * if the array isn't big enough, make a new + * one + */ + array = new char[datalen]; + } + data.getChars(0, datalen, array, 0); + contentHandler.characters(array, 0, datalen); + break; + case Node.PROCESSING_INSTRUCTION_NODE: + contentHandler.processingInstruction(currentNode.getNodeName(), + currentNode.getNodeValue()); + break; + case Node.ELEMENT_NODE: + NamedNodeMap map = currentNode.getAttributes(); + currentAtts.clear(); + for (int i = map.getLength() - 1; i >= 0; i--) { + Attr att = (Attr)map.item(i); + currentAtts.addAttribute(att.getNamespaceURI(), + att.getLocalName(), + att.getName(), "CDATA", + att.getValue()); + } + contentHandler.startElement(currentNode.getNamespaceURI(), + currentNode.getLocalName(), + currentNode.getNodeName(), + currentAtts); + break; + } + + Node nextNode = currentNode.getFirstChild(); + if (nextNode != null) { + currentNode = nextNode; + continue; + } + + while (currentNode != null) { + switch (currentNode.getNodeType()) { + case Node.DOCUMENT_NODE: + contentHandler.endDocument(); + break; + case Node.ELEMENT_NODE: + contentHandler.endElement(currentNode.getNamespaceURI(), + currentNode.getLocalName(), + currentNode.getNodeName()); + break; + } + + nextNode = currentNode.getNextSibling(); + if (nextNode != null) { + currentNode = nextNode; + break; + } + + currentNode = currentNode.getParentNode(); + } + } + + } else { + throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource"); + } + + } + + + + /** + * DocumentReader requires a DocumentInputSource, so this is not + * implements and simply throws a SAXException. Use parse(DocumentInputSource) + * instead + * + * @param systemId The system identifier (URI). + * @exception SAXException Any SAX exception, possibly + * wrapping another exception. + * @exception IOException An IO exception from the parser, + * possibly from a byte stream or character stream + * supplied by the application. + * @see #parse(org.xml.sax.InputSource) + */ + public void parse(String systemId) throws IOException, SAXException { + throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource"); + } + +} + + diff --git a/src/java/org/apache/fop/tools/TestConverter.java b/src/java/org/apache/fop/tools/TestConverter.java new file mode 100644 index 000000000..1f8449043 --- /dev/null +++ b/src/java/org/apache/fop/tools/TestConverter.java @@ -0,0 +1,391 @@ +/* + * $Id: TestConverter.java,v 1.23 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools; + +import org.apache.fop.apps.Driver; +import org.apache.fop.apps.FOInputHandler; +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.InputHandler; +import org.apache.fop.apps.XSLTInputHandler; +import org.apache.fop.fo.FOUserAgent; + +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.AbstractLogEnabled; + +import java.io.File; +import java.io.InputStream; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.XMLReader; +import org.xml.sax.SAXException; + +/** + * TestConverter is used to process a set of tests specified in + * a testsuite. + * This class retrieves the data in the testsuite and uses FOP + * to convert the xml and xsl file into either an xml representation + * of the area tree or a pdf document. + * The area tree can be used for automatic comparisons between different + * versions of FOP or the pdf can be view for manual checking and + * pdf rendering. + * + * Modified by Mark Lillywhite mark-fop@inomial.com to use the new Driver + * interface. + */ +public class TestConverter extends AbstractLogEnabled { + + private boolean failOnly = false; + private boolean outputPDF = false; + private File destdir; + private File compare = null; + private String baseDir = "./"; + private Map differ = new java.util.HashMap(); + + /** + * This main method can be used to run the test converter from + * the command line. + * This will take a specified testsuite xml and process all + * tests in it. + * The command line options are: + * -b to set the base directory for where the testsuite and associated files are + * -failOnly to process only the tests which are specified as fail in the test results + * -pdf to output the result as pdf + * @param args command-line arguments + */ + public static void main(String[] args) { + if (args == null || args.length == 0) { + System.out.println("test suite file name required"); + } + TestConverter tc = new TestConverter(); + tc.enableLogging(new ConsoleLogger(ConsoleLogger.LEVEL_ERROR)); + + String testFile = null; + for (int count = 0; count < args.length; count++) { + if (args[count].equals("-failOnly")) { + tc.setFailOnly(true); + } else if (args[count].equals("-pdf")) { + tc.setOutputPDF(true); + } else if (args[count].equals("-b")) { + tc.setBaseDir(args[count + 1]); + } else { + testFile = args[count]; + } + } + if (testFile == null) { + System.out.println("test suite file name required"); + } + + tc.runTests(testFile, "results", null); + } + + /** + * Controls whether to generate PDF or XML. + * @param pdf If True, PDF is generated, Area Tree XML otherwise. + */ + public void setOutputPDF(boolean pdf) { + outputPDF = pdf; + } + + /** + * Controls whether to process only the tests which are specified as fail + * in the test results. + * @param fail True if only fail tests should be processed + */ + public void setFailOnly(boolean fail) { + failOnly = fail; + } + + /** + * Sets the base directory. + * @param str base directory + */ + public void setBaseDir(String str) { + baseDir = str; + } + + /** + * Run the Tests. + * This runs the tests specified in the xml file fname. + * The document is read as a dom and each testcase is covered. + * @param fname filename of the input file + * @param dest destination directory + * @param compDir comparison directory + * @return Map a Map containing differences + */ + public Map runTests(String fname, String dest, String compDir) { + getLogger().debug("running tests in file:" + fname); + try { + if (compDir != null) { + compare = new File(baseDir + "/" + compDir); + } + destdir = new File(baseDir + "/" + dest); + destdir.mkdirs(); + File f = new File(baseDir + "/" + fname); + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + DocumentBuilder db = factory.newDocumentBuilder(); + Document doc = db.parse(f); + + NodeList suitelist = doc.getChildNodes(); + if (suitelist.getLength() == 0) { + return differ; + } + + Node testsuite = null; + testsuite = doc.getDocumentElement(); + + if (testsuite.hasAttributes()) { + String profile = + testsuite.getAttributes().getNamedItem("profile").getNodeValue(); + getLogger().debug("testing test suite:" + profile); + } + + NodeList testcases = testsuite.getChildNodes(); + for (int count = 0; count < testcases.getLength(); count++) { + Node testcase = testcases.item(count); + if (testcase.getNodeName().equals("testcases")) { + runTestCase(testcase); + } + } + } catch (Exception e) { + getLogger().error("Error while running tests", e); + } + return differ; + } + + /** + * Run a test case. + * This goes through a test case in the document. + * A testcase can contain a test, a result or more test cases. + * A test case is handled recursively otherwise the test is run. + * @param tcase Test case node to run + */ + protected void runTestCase(Node tcase) { + if (tcase.hasAttributes()) { + String profile = + tcase.getAttributes().getNamedItem("profile").getNodeValue(); + getLogger().debug("testing profile:" + profile); + } + + NodeList cases = tcase.getChildNodes(); + for (int count = 0; count < cases.getLength(); count++) { + Node node = cases.item(count); + String nodename = node.getNodeName(); + if (nodename.equals("testcases")) { + runTestCase(node); + } else if (nodename.equals("test")) { + runTest(tcase, node); + } else if (nodename.equals("result")) { + //nop + } + + } + + } + + /** + * Run a particular test. + * This runs a test defined by the xml and xsl documents. + * If the test has a result specified it is checked. + * This creates an XSLTInputHandler to provide the input + * for FOP and writes the data out to an XML are tree. + * @param testcase Test case to run + * @param test Test + */ + protected void runTest(Node testcase, Node test) { + String id = test.getAttributes().getNamedItem("id").getNodeValue(); + Node result = locateResult(testcase, id); + boolean pass = false; + if (result != null) { + String agreement = + result.getAttributes().getNamedItem("agreement").getNodeValue(); + pass = agreement.equals("full"); + } + + if (pass && failOnly) { + return; + } + + String xml = test.getAttributes().getNamedItem("xml").getNodeValue(); + Node xslNode = test.getAttributes().getNamedItem("xsl"); + String xsl = null; + if (xslNode != null) { + xsl = xslNode.getNodeValue(); + } + getLogger().debug("converting xml:" + xml + " and xsl:" + + xsl + " to area tree"); + + try { + File xmlFile = new File(baseDir + "/" + xml); + String baseURL = null; + try { + baseURL = xmlFile.getParentFile().toURL().toExternalForm(); + } catch (Exception e) { + getLogger().error("Error setting base directory"); + } + + InputHandler inputHandler = null; + if (xsl == null) { + inputHandler = new FOInputHandler(xmlFile); + } else { + inputHandler = new XSLTInputHandler(xmlFile, + new File(baseDir + "/" + + xsl)); + } + + XMLReader parser = inputHandler.getParser(); + setParserFeatures(parser); + + Driver driver = new Driver(); + setupLogger(driver, "fop"); + driver.initialize(); + FOUserAgent userAgent = new FOUserAgent(); + userAgent.setBaseURL(baseURL); + driver.setUserAgent(userAgent); + if (outputPDF) { + driver.setRenderer(Driver.RENDER_PDF); + } else { + driver.setRenderer(Driver.RENDER_XML); + } + + Map rendererOptions = new java.util.HashMap(); + rendererOptions.put("fineDetail", new Boolean(false)); + rendererOptions.put("consistentOutput", new Boolean(true)); + driver.getRenderer().setOptions(rendererOptions); + driver.getRenderer().setProducer("Testsuite Converter"); + + String outname = xmlFile.getName(); + if (outname.endsWith(".xml")) { + outname = outname.substring(0, outname.length() - 4); + } + driver.setOutputStream(new java.io.BufferedOutputStream( + new java.io.FileOutputStream(new File(destdir, + outname + (outputPDF ? ".pdf" : ".at.xml"))))); + getLogger().debug("ddir:" + destdir + " on:" + outname + ".pdf"); + driver.render(parser, inputHandler.getInputSource()); + + // check difference + if (compare != null) { + File f1 = new File(destdir, outname + ".at.xml"); + File f2 = new File(compare, outname + ".at.xml"); + if (!compareFiles(f1, f2)) { + differ.put(outname + ".at.xml", new Boolean(pass)); + } + } + } catch (Exception e) { + getLogger().error("Error while running tests", e); + } + } + + /** + * Compare files. + * @param f1 first file + * @param f2 second file + * @return true if equal + */ + protected boolean compareFiles(File f1, File f2) { + if (f1.length() != f2.length()) { + return false; + } + try { + InputStream is1 = new java.io.BufferedInputStream(new java.io.FileInputStream(f1)); + InputStream is2 = new java.io.BufferedInputStream(new java.io.FileInputStream(f2)); + while (true) { + int ch1 = is1.read(); + int ch2 = is2.read(); + if (ch1 == ch2) { + if (ch1 == -1) { + return true; + } + } else { + return false; + } + } + } catch (Exception e) { + getLogger().error("Error while comparing files", e); + } + + return false; + } + + private void setParserFeatures(XMLReader parser) throws FOPException { + try { + parser.setFeature("http://xml.org/sax/features/namespace-prefixes", + true); + } catch (SAXException e) { + throw new FOPException("Error in setting up parser feature namespace-prefixes\n" + + "You need a parser which supports SAX version 2", e); + } + } + + private Node locateResult(Node testcase, String id) { + NodeList cases = testcase.getChildNodes(); + for (int count = 0; count < cases.getLength(); count++) { + Node node = cases.item(count); + String nodename = node.getNodeName(); + if (nodename.equals("result")) { + String resultid = + node.getAttributes().getNamedItem("id").getNodeValue(); + if (id.equals(resultid)) { + return node; + } + } + } + return null; + } + +} diff --git a/src/java/org/apache/fop/tools/anttasks/Compare.java b/src/java/org/apache/fop/tools/anttasks/Compare.java new file mode 100644 index 000000000..ca3ab5182 --- /dev/null +++ b/src/java/org/apache/fop/tools/anttasks/Compare.java @@ -0,0 +1,235 @@ +/* + * $Id: Compare.java,v 1.5 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.anttasks; + +import java.util.Date; +import java.util.List; +import java.util.StringTokenizer; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; + +import org.apache.tools.ant.BuildException; +import java.text.DateFormat; + +/** + * This class is an extension of Ant, a script utility from + * http://ant.apache.org. + * It provides methods to compare two files. + */ + +public class Compare { + + private static final boolean IDENTICAL_FILES = true; + private static final boolean NOTIDENTICAL_FILES = false; + + private String referenceDirectory, testDirectory; + private String[] filenameList; + private String filenames; + private BufferedInputStream oldfileInput; + private BufferedInputStream newfileInput; + + /** + * Sets directory for test files. + * @param testDirectory the test directory + */ + public void setTestDirectory(String testDirectory) { + if (!(testDirectory.endsWith("/") | testDirectory.endsWith("\\"))) { + testDirectory += File.separator; + } + this.testDirectory = testDirectory; + } + + /** + * Sets directory for reference files. + * @param referenceDirectory the reference directory + */ + public void setReferenceDirectory(String referenceDirectory) { + if (!(referenceDirectory.endsWith("/") + | referenceDirectory.endsWith("\\"))) { + referenceDirectory += File.separator; + } + this.referenceDirectory = referenceDirectory; + } + + /** + * Sets the comma-separated list of files to process. + * @param filenames list of files, comma-separated + */ + public void setFilenames(String filenames) { + StringTokenizer tokens = new StringTokenizer(filenames, ","); + List filenameListTmp = new java.util.ArrayList(20); + while (tokens.hasMoreTokens()) { + filenameListTmp.add(tokens.nextToken()); + } + filenameList = new String[filenameListTmp.size()]; + filenameList = (String[])filenameListTmp.toArray(new String[0]); + } + + private boolean compareBytes(File oldFile, File newFile) { + try { + oldfileInput = + new BufferedInputStream(new java.io.FileInputStream(oldFile)); + newfileInput = + new BufferedInputStream(new java.io.FileInputStream(newFile)); + int charactO = 0; + int charactN = 0; + boolean identical = true; + + while (identical & (charactO != -1)) { + if (charactO == charactN) { + charactO = oldfileInput.read(); + charactN = newfileInput.read(); + } else { + return NOTIDENTICAL_FILES; + } + } + return IDENTICAL_FILES; + } catch (IOException io) { + System.err.println("Task Compare - Error: \n" + io.toString()); + } + return NOTIDENTICAL_FILES; + } + + private boolean compareFileSize(File oldFile, File newFile) { + if (oldFile.length() != newFile.length()) { + return NOTIDENTICAL_FILES; + } else { + return IDENTICAL_FILES; + } + } // end: compareBytes + + private boolean filesExist(File oldFile, File newFile) { + if (!oldFile.exists()) { + System.err.println("Task Compare - ERROR: File " + + referenceDirectory + oldFile.getName() + + " doesn't exist!"); + return false; + } else if (!newFile.exists()) { + System.err.println("Task Compare - ERROR: File " + testDirectory + + newFile.getName() + " doesn't exist!"); + return false; + } else { + return true; + } + } + + private void writeHeader(PrintWriter results) { + String dateTime = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, + DateFormat.MEDIUM).format(new Date()); + results.println("Test Results\n"); + results.println("

Compare Results
"); + results.println("created " + dateTime + + "

"); + results.println("" + + "" + + "" + + ""); + + + } + + /** + * Main method of task compare + * @throws BuildException If the execution fails. + */ + public void execute() throws BuildException { + boolean identical = false; + File oldFile; + File newFile; + try { + PrintWriter results = + new PrintWriter(new java.io.FileWriter("results.html"), true); + this.writeHeader(results); + for (int i = 0; i < filenameList.length; i++) { + oldFile = new File(referenceDirectory + filenameList[i]); + newFile = new File(testDirectory + filenameList[i]); + if (filesExist(oldFile, newFile)) { + identical = compareFileSize(oldFile, newFile); + if (identical) { + identical = compareBytes(oldFile, newFile); + } + if (!identical) { + System.out.println("Task Compare: \nFiles " + + referenceDirectory + + oldFile.getName() + " - " + + testDirectory + + newFile.getName() + + " are *not* identical."); + results.println(""); + } else { + results.println(""); + } + } + } + results.println("
reference filetest fileidentical?
" + + oldFile.getName() + + " " + newFile.getName() + "" + + " No
" + + oldFile.getName() + + " " + newFile.getName() + "" + + " Yes
"); + } catch (IOException ioe) { + System.err.println("ERROR: " + ioe); + } + } // end: execute() + +} + diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java new file mode 100644 index 000000000..2dc3fd933 --- /dev/null +++ b/src/java/org/apache/fop/tools/anttasks/Fop.java @@ -0,0 +1,503 @@ +/* + * $Id: Fop.java,v 1.24 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.anttasks; + +// Ant +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.util.GlobPatternMapper; + +// SAX +import org.xml.sax.XMLReader; + +// Java +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.util.List; + +// FOP +import org.apache.fop.apps.Starter; +import org.apache.fop.apps.InputHandler; +import org.apache.fop.apps.FOInputHandler; +import org.apache.fop.apps.Driver; +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FOUserAgent; + +// Avalon +import org.apache.avalon.framework.logger.ConsoleLogger; +import org.apache.avalon.framework.logger.Logger; + +/** + * Wrapper for FOP which allows it to be accessed from within an Ant task. + * Accepts the inputs: + *
    + *
  • fofile -> formatting objects file to be transformed
  • + *
  • format -> MIME type of the format to generate ex. "application/pdf"
  • + *
  • outfile -> output filename
  • + *
  • baseDir -> directory to work from
  • + *
  • userconfig -> file with user configuration (same as the "-c" command + * line option)
  • + *
  • messagelevel -> (error | warn | info | verbose | debug) level to output + * non-error messages
  • + *
  • logFiles -> Controls whether the names of the files that are processed + * are logged or not
  • + *
+ */ +public class Fop extends Task { + + private File foFile; + private List filesets = new java.util.ArrayList(); + private File outFile; + private File outDir; + private String format; //MIME type + private File baseDir; + private File userConfig; + private int messageType = Project.MSG_VERBOSE; + private boolean logFiles = true; + + /** + * Sets the filename for the userconfig.xml. + * @param userConfig Configuration to use + */ + public void setUserconfig(File userConfig) { + this.userConfig = userConfig; + } + + /** + * Returns the file for the userconfig.xml. + * @return the userconfig.xml file + */ + public File getUserconfig() { + return this.userConfig; + } + + /** + * Sets the input XSL-FO file. + * @param foFile input XSL-FO file + */ + public void setFofile(File foFile) { + this.foFile = foFile; + } + + /** + * Gets the input XSL-FO file. + * @return input XSL-FO file + */ + public File getFofile() { + return foFile; + } + + /** + * Adds a set of XSL-FO files (nested fileset attribute). + * @param set a fileset + */ + public void addFileset(FileSet set) { + filesets.add(set); + } + + /** + * Returns the current list of filesets. + * @return the filesets + */ + public List getFilesets() { + return this.filesets; + } + + /** + * Sets the output file. + * @param outFile File to output to + */ + public void setOutfile(File outFile) { + this.outFile = outFile; + } + + /** + * Gets the output file. + * @return the output file + */ + public File getOutfile() { + return this.outFile; + } + + /** + * Sets the output directory. + * @param outDir Directory to output to + */ + public void setOutdir(File outDir) { + this.outDir = outDir; + } + + /** + * Gets the output directory. + * @return the output directory + */ + public File getOutdir() { + return this.outDir; + } + + /** + * Sets output format (MIME type). + * @param format the output format + */ + public void setFormat(String format) { + this.format = format; + } + + /** + * Gets the output format (MIME type). + * @return the output format + */ + public String getFormat() { + return this.format; + } + + /** + * Sets the message level to be used while processing. + * @param messageLevel (error | warn| info | verbose | debug) + */ + public void setMessagelevel(String messageLevel) { + if (messageLevel.equalsIgnoreCase("info")) { + messageType = Project.MSG_INFO; + } else if (messageLevel.equalsIgnoreCase("verbose")) { + messageType = Project.MSG_VERBOSE; + } else if (messageLevel.equalsIgnoreCase("debug")) { + messageType = Project.MSG_DEBUG; + } else if (messageLevel.equalsIgnoreCase("err") + || messageLevel.equalsIgnoreCase("error")) { + messageType = Project.MSG_ERR; + } else if (messageLevel.equalsIgnoreCase("warn")) { + messageType = Project.MSG_WARN; + } else { + log("messagelevel set to unknown value \"" + messageLevel + + "\"", Project.MSG_ERR); + throw new BuildException("unknown messagelevel"); + } + } + + /** + * Returns the message type corresponding to Project.MSG_* + * representing the current message level. + * @see org.apache.tools.ant.Project + */ + public int getMessageType() { + return messageType; + } + + /** + * Sets the base directory; currently ignored. + * @param baseDir File to use as a working directory + */ + public void setBasedir(File baseDir) { + this.baseDir = baseDir; + } + + /** + * Gets the base directory. + * @return the base directory + */ + public File getBasedir() { + return (baseDir != null) ? baseDir : project.resolveFile("."); + } + + /** + * Controls whether the filenames of the files that are processed are logged + * or not. + * @param logFiles True if the feature should be enabled + */ + public void setLogFiles(boolean logFiles) { + this.logFiles = logFiles; + } + + /** + * Returns True if the filename of each file processed should be logged. + * @return True if the filenames should be logged. + */ + public boolean getLogFiles() { + return this.logFiles; + } + + /** + * @see org.apache.tools.ant.Task#execute() + */ + public void execute() throws BuildException { + int logLevel = ConsoleLogger.LEVEL_INFO; + switch (getMessageType()) { + case Project.MSG_DEBUG : logLevel = ConsoleLogger.LEVEL_DEBUG; break; + case Project.MSG_INFO : logLevel = ConsoleLogger.LEVEL_INFO; break; + case Project.MSG_WARN : logLevel = ConsoleLogger.LEVEL_WARN; break; + case Project.MSG_ERR : logLevel = ConsoleLogger.LEVEL_ERROR; break; + case Project.MSG_VERBOSE: logLevel = ConsoleLogger.LEVEL_DEBUG; break; + } + Logger log = new ConsoleLogger(logLevel); + try { + Starter starter = new FOPTaskStarter(this); + starter.enableLogging(log); + starter.run(); + } catch (FOPException ex) { + throw new BuildException(ex); + } + + } + +} + +class FOPTaskStarter extends Starter { + + private Fop task; + private String baseURL = null; + + FOPTaskStarter(Fop task) throws FOPException { + this.task = task; + } + + private int determineRenderer(String format) { + if ((format == null) + || format.equalsIgnoreCase("application/pdf") + || format.equalsIgnoreCase("pdf")) { + return Driver.RENDER_PDF; + } else if (format.equalsIgnoreCase("application/postscript") + || format.equalsIgnoreCase("ps")) { + return Driver.RENDER_PS; + } else if (format.equalsIgnoreCase("application/vnd.mif") + || format.equalsIgnoreCase("mif")) { + return Driver.RENDER_MIF; + } else if (format.equalsIgnoreCase("application/msword") + || format.equalsIgnoreCase("application/rtf") + || format.equalsIgnoreCase("rtf")) { + return Driver.RENDER_RTF; + } else if (format.equalsIgnoreCase("application/vnd.hp-PCL") + || format.equalsIgnoreCase("pcl")) { + return Driver.RENDER_PCL; + } else if (format.equalsIgnoreCase("text/plain") + || format.equalsIgnoreCase("txt")) { + return Driver.RENDER_TXT; + } else if (format.equalsIgnoreCase("text/xml") + || format.equalsIgnoreCase("at") + || format.equalsIgnoreCase("xml")) { + return Driver.RENDER_XML; + } else { + String err = "Couldn't determine renderer to use: " + format; + throw new BuildException(err); + } + } + + private String determineExtension(int renderer) { + switch (renderer) { + case Driver.RENDER_PDF: + return ".pdf"; + case Driver.RENDER_PS: + return ".ps"; + case Driver.RENDER_MIF: + return ".mif"; + case Driver.RENDER_RTF: + return ".rtf"; + case Driver.RENDER_PCL: + return ".pcl"; + case Driver.RENDER_TXT: + return ".txt"; + case Driver.RENDER_XML: + return ".xml"; + default: + String err = "Unknown renderer: " + renderer; + throw new BuildException(err); + } + } + + private File replaceExtension(File file, String expectedExt, + String newExt) { + String name = file.getName(); + if (name.toLowerCase().endsWith(expectedExt)) { + name = name.substring(0, name.length() - expectedExt.length()); + } + name = name.concat(newExt); + return new File(file.getParentFile(), name); + } + + /** + * @see org.apache.fop.apps.Starter#run() + */ + public void run() throws FOPException { + //Setup configuration + if (task.getUserconfig() != null) { + /**@todo implement me */ + } + + //Set base directory + if (task.getBasedir() != null) { + try { + this.baseURL = task.getBasedir().toURL().toExternalForm(); + } catch (MalformedURLException mfue) { + getLogger().error("Error creating base URL from base directory", mfue); + } + } else { + try { + if (task.getFofile() != null) { + this.baseURL = task.getFofile().getParentFile().toURL(). + toExternalForm(); + } + } catch (MalformedURLException mfue) { + getLogger().error("Error creating base URL from XSL-FO input file", mfue); + } + } + + task.log("Using base URL: " + baseURL, Project.MSG_DEBUG); + + int rint = determineRenderer(task.getFormat()); + String newExtension = determineExtension(rint); + + int actioncount = 0; + + // deal with single source file + if (task.getFofile() != null) { + if (task.getFofile().exists()) { + File outf = task.getOutfile(); + if (outf == null) { + throw new BuildException("outfile is required when fofile is used"); + } + if (task.getOutdir() != null) { + outf = new File(task.getOutdir(), outf.getName()); + } + render(task.getFofile(), outf, rint); + actioncount++; + } + } + + GlobPatternMapper mapper = new GlobPatternMapper(); + mapper.setFrom("*.fo"); + mapper.setTo("*" + newExtension); + + // deal with the filesets + for (int i = 0; i < task.getFilesets().size(); i++) { + FileSet fs = (FileSet) task.getFilesets().get(i); + DirectoryScanner ds = fs.getDirectoryScanner(task.getProject()); + String[] files = ds.getIncludedFiles(); + + for (int j = 0; j < files.length; j++) { + File f = new File(fs.getDir(task.getProject()), files[j]); + + File outf = null; + if (task.getOutdir() != null && files[j].endsWith(".fo")) { + String[] sa = mapper.mapFileName(files[j]); + outf = new File(task.getOutdir(), sa[0]); + } else { + outf = replaceExtension(f, ".fo", newExtension); + if (task.getOutdir() != null) { + outf = new File(task.getOutdir(), outf.getName()); + } + } + + try { + if (this.baseURL == null) { + this.baseURL = fs.getDir(task.getProject()).toURL(). + toExternalForm(); + } + + } catch (Exception e) { + task.log("Error setting base URL", Project.MSG_DEBUG); + } + + render(f, outf, rint); + actioncount++; + } + } + + if (actioncount == 0) { + task.log("No files processed. No files were selected by the filesets " + + "and no fofile was set." , Project.MSG_WARN); + } + } + + private void render(File foFile, File outFile, + int renderer) throws FOPException { + InputHandler inputHandler = new FOInputHandler(foFile); + XMLReader parser = inputHandler.getParser(); + setParserFeatures(parser); + + OutputStream out = null; + try { + out = new java.io.FileOutputStream(outFile); + } catch (Exception ex) { + throw new BuildException("Failed to open " + outFile, ex); + } + + if (task.getLogFiles()) { + task.log(foFile + " -> " + outFile, Project.MSG_INFO); + } + + try { + Driver driver = new Driver(); + setupLogger(driver); + driver.initialize(); + FOUserAgent userAgent = new FOUserAgent(); + userAgent.setBaseURL(this.baseURL); + userAgent.enableLogging(getLogger()); + driver.setUserAgent(userAgent); + driver.setRenderer(renderer); + driver.setOutputStream(out); + driver.render(parser, inputHandler.getInputSource()); + } catch (Exception ex) { + throw new BuildException(ex); + } finally { + try { + out.close(); + } catch (IOException ioe) { + getLogger().error("Error closing output file", ioe); + } + } + } + +} + diff --git a/src/java/org/apache/fop/tools/anttasks/RunTest.java b/src/java/org/apache/fop/tools/anttasks/RunTest.java new file mode 100644 index 000000000..1fa6d00dc --- /dev/null +++ b/src/java/org/apache/fop/tools/anttasks/RunTest.java @@ -0,0 +1,256 @@ +/* + * $Id: RunTest.java,v 1.8 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.anttasks; + +// Ant +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +// Java +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URLClassLoader; +import java.net.URL; +import java.net.MalformedURLException; +import java.util.Iterator; +import java.util.Map; + + +/** + * Testing ant task. + * This task is used to test FOP as a build target. + * This uses the TestConverter (with weak code dependancy) to run the tests + * and check the results. + */ +public class RunTest extends Task { + + private String basedir; + private String testsuite = ""; + private String referenceJar = ""; + private String refVersion = ""; + + /** + * Sets the test suite name. + * @param str name of the test suite + */ + public void setTestSuite(String str) { + testsuite = str; + } + + /** + * Sets the base directory. + * @param str base directory + */ + public void setBasedir(String str) { + basedir = str; + } + + /** + * Sets the reference directory. + * @param str reference directory + */ + public void setReference(String str) { + referenceJar = str; + } + + /** + * Sets the reference version. + * @param str reference version + */ + public void setRefVersion(String str) { + refVersion = str; + } + + /** + * This creates the reference output, if required, then tests + * the current build. + * @see org.apache.tools.ant.Task#execute() + */ + public void execute() throws BuildException { + runReference(); + testNewBuild(); + } + + /** + * Test the current build. + * This uses the current jar file (in build/fop.jar) to run the + * tests with. + * The output is then compared with the reference output. + */ + protected void testNewBuild() { + try { + ClassLoader loader = new URLClassLoader(new URL[] { + new URL("file:build/fop.jar") + }); + Map diff = runConverter(loader, "areatree", + "reference/output/"); + if (diff != null && !diff.isEmpty()) { + System.out.println("===================================="); + System.out.println("The following files differ:"); + boolean broke = false; + for (Iterator keys = diff.keySet().iterator(); + keys.hasNext();) { + Object fname = keys.next(); + Boolean pass = (Boolean)diff.get(fname); + System.out.println("file: " + fname + + " - reference success: " + pass); + if (pass.booleanValue()) { + broke = true; + } + } + if (broke) { + throw new BuildException("Working tests have been changed."); + } + } + } catch (MalformedURLException mue) { + mue.printStackTrace(); + } + } + + /** + * Run the tests for the reference jar file. + * This checks that the reference output has not already been + * run and then checks the version of the reference jar against + * the version required. + * The reference output is then created. + * @throws BuildException if an error occurs + */ + protected void runReference() throws BuildException { + // check not already done + File f = new File(basedir + "/reference/output/"); + // if(f.exists()) { + // need to check that files have actually been created. + // return; + // } else { + try { + ClassLoader loader = new URLClassLoader(new URL[] { + new URL("file:" + referenceJar) + }); + boolean failed = false; + + try { + Class cla = Class.forName("org.apache.fop.apps.Options", + true, loader); + /*Object opts =*/ cla.newInstance(); + cla = Class.forName("org.apache.fop.apps.Version", true, + loader); + Method get = cla.getMethod("getVersion", new Class[]{}); + if (!get.invoke(null, new Object[]{}).equals(refVersion)) { + throw new BuildException("Reference jar is not correct version it must be: " + + refVersion); + } + } catch (IllegalAccessException iae) { + failed = true; + } catch (IllegalArgumentException are) { + failed = true; + } catch (InvocationTargetException are) { + failed = true; + } catch (ClassNotFoundException are) { + failed = true; + } catch (InstantiationException are) { + failed = true; + } catch (NoSuchMethodException are) { + failed = true; + } + if (failed) { + throw new BuildException("Reference jar could not be found in: " + + basedir + "/reference/"); + } + f.mkdirs(); + runConverter(loader, "reference/output/", null); + } catch (MalformedURLException mue) { + mue.printStackTrace(); + } + // } + } + + /** + * Run the Converter. + * Runs the test converter using the specified class loader. + * This loads the TestConverter using the class loader and + * then runs the test suite for the current test suite + * file in the base directory. + * @param loader the class loader to use to run the tests with + * @param dest destination directory + * @param compDir comparison directory + * @return A Map with differences + */ + protected Map runConverter(ClassLoader loader, String dest, + String compDir) { + String converter = "org.apache.fop.tools.TestConverter"; + + Map diff = null; + try { + Class cla = Class.forName(converter, true, loader); + Object tc = cla.newInstance(); + Method meth; + + meth = cla.getMethod("setBaseDir", new Class[] { + String.class + }); + meth.invoke(tc, new Object[] { + basedir + }); + + meth = cla.getMethod("runTests", new Class[] { + String.class, String.class, String.class + }); + diff = (Map)meth.invoke(tc, new Object[] { + testsuite, dest, compDir + }); + } catch (Exception e) { + e.printStackTrace(); + } + return diff; + } + +} diff --git a/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java b/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java new file mode 100644 index 000000000..8a15847a1 --- /dev/null +++ b/src/java/org/apache/fop/tools/anttasks/SerializeHyphPattern.java @@ -0,0 +1,197 @@ +/* + * $Id: SerializeHyphPattern.java,v 1.5 2003/03/07 10:09:30 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.anttasks; + +// Java +import java.io.File; +import java.io.IOException; +import java.io.ObjectOutputStream; + +// Ant +import org.apache.tools.ant.taskdefs.MatchingTask; +import org.apache.tools.ant.DirectoryScanner; + +// FOP +import org.apache.fop.layout.hyphenation.HyphenationTree; +import org.apache.fop.layout.hyphenation.HyphenationException; + +/** + * SerializeHyphPattern + */ + + +public class SerializeHyphPattern extends MatchingTask { + private File sourceDir, targetDir; + private boolean errorDump = false; + + /** + * @see org.apache.tools.ant.Task#execute() + */ + public void execute() throws org.apache.tools.ant.BuildException { + DirectoryScanner ds = this.getDirectoryScanner(sourceDir); + String[] files = ds.getIncludedFiles(); + for (int i = 0; i < files.length; i++) { + processFile(files[i].substring(0, files[i].length() - 4)); + } + } // end execute + + + /** + * Sets the source directory. + * @param sourceDir source directory + */ + public void setSourceDir(String sourceDir) { + File dir = new File(sourceDir); + if (!dir.exists()) { + System.err.println("Fatal Error: source directory " + sourceDir + + " for hyphenation files doesn't exist."); + System.exit(1); + } + this.sourceDir = dir; + } + + /** + * Sets the target directory + * @param targetDir target directory + */ + public void setTargetDir(String targetDir) { + File dir = new File(targetDir); + this.targetDir = dir; + } + + /** + * Controls the amount of error information dumped. + * @param errorDump True if more error info should be provided + */ + public void setErrorDump(boolean errorDump) { + this.errorDump = errorDump; + } + + + /* + * checks whether input or output files exists or the latter is older than input file + * and start build if necessary + */ + private void processFile(String filename) { + File infile = new File(sourceDir, filename + ".xml"); + File outfile = new File(targetDir, filename + ".hyp"); + //long outfileLastModified = outfile.lastModified(); + boolean startProcess = true; + + startProcess = rebuild(infile, outfile); + if (startProcess) { + buildPatternFile(infile, outfile); + } + } + + /* + * serializes pattern files + */ + private void buildPatternFile(File infile, File outfile) { + System.out.println("Processing " + infile); + HyphenationTree hTree = new HyphenationTree(); + try { + hTree.loadPatterns(infile.toString()); + if (errorDump) { + System.out.println("Stats: "); + hTree.printStats(); + } + } catch (HyphenationException ex) { + System.err.println("Can't load patterns from xml file " + infile + + " - Maybe hyphenation.dtd is missing?"); + if (errorDump) { + System.err.println(ex.toString()); + } + } + // serialize class + try { + ObjectOutputStream out = new ObjectOutputStream( + new java.io.BufferedOutputStream( + new java.io.FileOutputStream(outfile))); + out.writeObject(hTree); + out.close(); + } catch (IOException ioe) { + System.err.println("Can't write compiled pattern file: " + + outfile); + System.err.println(ioe); + } + } + + /** + * Checks for existence of output file and compares + * dates with input and stylesheet file + */ + private boolean rebuild(File infile, File outfile) { + if (outfile.exists()) { + // checks whether output file is older than input file + if (outfile.lastModified() < infile.lastModified()) { + return true; + } + } else { + // if output file does not exist, start process + return true; + } + return false; + } // end rebuild + + /* + * //quick access for debugging + * public static void main (String args[]) { + * SerializeHyphPattern ser = new SerializeHyphPattern(); + * ser.setIncludes("*.xml"); + * ser.setSourceDir("\\xml-fop\\hyph\\"); + * ser.setTargetDir("\\xml-fop\\hyph\\"); + * ser.execute(); + * } + */ + + +} diff --git a/src/java/org/apache/fop/tools/xslt/TraxTransform.java b/src/java/org/apache/fop/tools/xslt/TraxTransform.java new file mode 100644 index 000000000..c2d227b1a --- /dev/null +++ b/src/java/org/apache/fop/tools/xslt/TraxTransform.java @@ -0,0 +1,194 @@ +/* + * $Id: TraxTransform.java,v 1.5 2003/03/07 10:09:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.xslt; + +import java.io.InputStream; +import java.io.Writer; +import java.util.Map; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; + +import org.w3c.dom.Document; + +/** + * Handles xslt tranformations via Trax (xalan2) + */ +public class TraxTransform { + + /** + * Cache of compiled stylesheets (filename, StylesheetRoot) + */ + private static Map stylesheetCache = new java.util.Hashtable(); + + /** + * Gets a Trax transformer + * @param xsltFilename Filename of the XSLT file + * @param cache True, if caching of the stylesheet is allowed + * @return Transformer the Trax transformer + */ + public static Transformer getTransformer(String xsltFilename, + boolean cache) { + try { + if (cache && stylesheetCache.containsKey(xsltFilename)) { + Templates cachedStylesheet = + (Templates)stylesheetCache.get(xsltFilename); + return cachedStylesheet.newTransformer(); + } + + Source xslSheet = + new javax.xml.transform.stream.StreamSource(xsltFilename); + + + /* + * System.out.println("****************************"); + * System.out.println("trax compile \nin: " + xsltFilename); + * System.out.println("****************************"); + */ + TransformerFactory factory = TransformerFactory.newInstance(); + + Templates compiledSheet = factory.newTemplates(xslSheet); + if (cache) { + stylesheetCache.put(xsltFilename, compiledSheet); + } + return compiledSheet.newTransformer(); + } catch (TransformerConfigurationException ex) { + ex.printStackTrace(); + } + return null; + + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Filename of the source XML file + * @param xslURL Filename of the XSLT filename + * @param outputFile Target filename + */ + public static void transform(String xmlSource, String xslURL, + String outputFile) { + transform(new javax.xml.transform.stream.StreamSource(xmlSource), + new javax.xml.transform.stream.StreamSource(xslURL), + new javax.xml.transform.stream.StreamResult(outputFile)); + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Source DOM Document + * @param xslURL Filename of the XSLT filename + * @param outputFile Target filename + */ + public static void transform(Document xmlSource, String xslURL, + String outputFile) { + + transform(new javax.xml.transform.dom.DOMSource(xmlSource), + new javax.xml.transform.stream.StreamSource(xslURL), + new javax.xml.transform.stream.StreamResult(outputFile)); + + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Filename of the source XML file + * @param xslURL Filename of the XSLT filename + * @param output Target Writer instance + */ + public static void transform(String xmlSource, String xslURL, + Writer output) { + transform(new javax.xml.transform.stream.StreamSource(xmlSource), + new javax.xml.transform.stream.StreamSource(xslURL), + new javax.xml.transform.stream.StreamResult(output)); + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Source DOM Document + * @param xsl Filename of the XSLT filename + * @param outputDoc Target DOM document + */ + public static void transform(Document xmlSource, InputStream xsl, + Document outputDoc) { + transform(new javax.xml.transform.dom.DOMSource(xmlSource), + new javax.xml.transform.stream.StreamSource(xsl), + new javax.xml.transform.dom.DOMResult(outputDoc)); + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource XML Source + * @param xslSource XSLT Source + * @param result Target Result + */ + public static void transform(Source xmlSource, Source xslSource, + Result result) { + try { + Transformer transformer; + if (xslSource.getSystemId() == null) { + TransformerFactory factory = TransformerFactory.newInstance(); + transformer = factory.newTransformer(xslSource); + } else { + transformer = getTransformer(xslSource.getSystemId(), true); + } + transformer.transform(xmlSource, result); + } catch (TransformerConfigurationException ex) { + ex.printStackTrace(); + } catch (TransformerException ex) { + ex.printStackTrace(); + } + + } + +} diff --git a/src/java/org/apache/fop/tools/xslt/XSLTransform.java b/src/java/org/apache/fop/tools/xslt/XSLTransform.java new file mode 100644 index 000000000..9f76567a9 --- /dev/null +++ b/src/java/org/apache/fop/tools/xslt/XSLTransform.java @@ -0,0 +1,215 @@ +/* + * $Id: XSLTransform.java,v 1.5 2003/03/07 10:09:31 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.tools.xslt; + +import java.io.InputStream; +import java.io.Writer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Class for transforming XML using XSLT. Wraps either Trax (JAXP) or Xalan 1.x. + */ +public class XSLTransform { + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Filename of the source XML file + * @param xslURL Filename of the XSLT filename + * @param outputFile Target filename + * @throws Exception If the conversion fails + */ + public static void transform(String xmlSource, String xslURL, + String outputFile) throws Exception { + Class[] argTypes = { + String.class, String.class, String.class + }; + Object[] params = { + xmlSource, xslURL, outputFile + }; + transform(params, argTypes); + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Source DOM Document + * @param xslURL Filename of the XSLT filename + * @param outputFile Target filename + * @throws Exception If the conversion fails + */ + public static void transform(org.w3c.dom.Document xmlSource, + String xslURL, + String outputFile) throws Exception { + Class[] argTypes = { + org.w3c.dom.Document.class, String.class, String.class + }; + + Object[] params = { + xmlSource, xslURL, outputFile + }; + transform(params, argTypes); + + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Filename of the source XML file + * @param xslURL Filename of the XSLT filename + * @param outputWriter Target Writer instance + * @throws Exception If the conversion fails + */ + public static void transform(String xmlSource, String xslURL, + Writer outputWriter) throws Exception { + Class[] argTypes = { + String.class, String.class, Writer.class + }; + Object[] params = { + xmlSource, xslURL, outputWriter + }; + transform(params, argTypes); + + } + + /** + * Transforms an XML file using XSLT. + * @param xmlSource Source DOM Document + * @param xsl Filename of the XSLT filename + * @param outputDoc Target DOM document + * @throws Exception If the conversion fails + */ + public static void transform(org.w3c.dom.Document xmlSource, + InputStream xsl, + org.w3c.dom.Document outputDoc) throws Exception { + Class[] argTypes = { + org.w3c.dom.Document.class, InputStream.class, + org.w3c.dom.Document.class + }; + Object[] params = { + xmlSource, xsl, outputDoc + }; + transform(params, argTypes); + + } + + + private static void transform(Object[] args, + Class[] argTypes) throws Exception { + Class transformer = getTransformClass(); + if (transformer != null) { + Method transformMethod = getTransformMethod(transformer, + argTypes); + if (transformMethod != null) { + try { + transformMethod.invoke(null, args); + } catch (InvocationTargetException ex) { + ex.printStackTrace(); + } + } else { + throw new Exception("transform method not found"); + } + } else { + throw new Exception("no transformer class found"); + } + + } + + + private static Class getTransformClass() { + try { + // try trax first + Class transformer = + Class.forName("javax.xml.transform.Transformer"); + // ok, make sure we have a liaison to trax + transformer = + Class.forName("org.apache.fop.tools.xslt.TraxTransform"); + return transformer; + + } catch (ClassNotFoundException ex) { + //nop + } + // otherwise, try regular xalan1 + try { + Class transformer = + Class.forName("org.apache.xalan.xslt.XSLTProcessor"); + // get the liaison + transformer = + Class.forName("org.apache.fop.tools.xslt.Xalan1Transform"); + return transformer; + } catch (ClassNotFoundException ex) { + //nop + } + return null; + + } + + + private static Method getTransformMethod(Class c, Class[] argTypes) { + // System.out.println("transformer class = "+c); + + try { + // Class[] argTypes = new Class[args.length]; + for (int i = 0; i < argTypes.length; i++) { + // argTypes[i] = args[i].getClass(); + // System.out.println("arg["+i+"] type = "+argTypes[i]); + + } + + Method transformer = c.getMethod("transform", argTypes); + return transformer; + + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + + } + return null; + } + +} diff --git a/src/java/org/apache/fop/traits/BlockProps.java b/src/java/org/apache/fop/traits/BlockProps.java new file mode 100644 index 000000000..5099d2f78 --- /dev/null +++ b/src/java/org/apache/fop/traits/BlockProps.java @@ -0,0 +1,65 @@ +/* + * $Id: BlockProps.java,v 1.3 2003/03/07 10:09:40 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.traits; + +/** + * Store all block-level layout properties on an FO. + * Public "structure" allows direct member access. + */ +public class BlockProps { + + public int firstIndent; // text-indent + public int lastIndent; // last-line-indent + public int textAlign; + public int textAlignLast; + public int lineStackType; // line-stacking-strategy (enum) + +} diff --git a/src/java/org/apache/fop/traits/BorderProps.java b/src/java/org/apache/fop/traits/BorderProps.java new file mode 100644 index 000000000..a9f619833 --- /dev/null +++ b/src/java/org/apache/fop/traits/BorderProps.java @@ -0,0 +1,84 @@ +/* + * $Id: BorderProps.java,v 1.4 2003/03/07 10:09:40 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.traits; + +import org.apache.fop.datatypes.ColorType; + +import java.io.Serializable; + +/** + * Border properties. + * Class to store border trait propties for the area tree. + */ +public class BorderProps implements Serializable { + + public int style; // Enum for border style + public ColorType color; // Border color + public int width; // Border width + + public BorderProps(int style, int width, ColorType color) { + this.style = style; + this.width = width; + this.color = color; + } + + public String toString() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append('('); + sbuf.append(style); // Should get a String value for this enum constant + sbuf.append(','); + sbuf.append(color); + sbuf.append(','); + sbuf.append(width); + sbuf.append(')'); + return sbuf.toString(); + } +} diff --git a/src/java/org/apache/fop/traits/InlineProps.java b/src/java/org/apache/fop/traits/InlineProps.java new file mode 100644 index 000000000..e2f91a991 --- /dev/null +++ b/src/java/org/apache/fop/traits/InlineProps.java @@ -0,0 +1,66 @@ +/* + * $Id: InlineProps.java,v 1.2 2003/03/07 10:09:40 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.traits; + +/** + * Store all inline "margin" related properties + * Public "structure" allows direct member access. + */ +public class InlineProps { + + public int marginTop; + public int marginBottom; + public int marginLeft; + public int marginRight; + public SpaceVal spaceStart; + public SpaceVal spaceEnd; + +} diff --git a/src/java/org/apache/fop/traits/LayoutProps.java b/src/java/org/apache/fop/traits/LayoutProps.java new file mode 100644 index 000000000..002901a56 --- /dev/null +++ b/src/java/org/apache/fop/traits/LayoutProps.java @@ -0,0 +1,103 @@ +/* + * $Id: LayoutProps.java,v 1.4 2003/03/07 10:09:40 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.traits; + +import org.apache.fop.fo.properties.Constants; + +/** + * Store properties affecting layout: break-before, break-after, keeps, span. + * for a block level FO. + * Public "structure" allows direct member access. + */ +public class LayoutProps { + + public int breakBefore; // enum constant BreakBefore.xxx + public int breakAfter; // enum constant BreakAfter.xxx + public boolean bIsSpan; + public SpaceVal spaceBefore; + public SpaceVal spaceAfter; + + private static final int[] BREAK_PRIORITIES = + new int[]{ Constants.AUTO, Constants.COLUMN, Constants.PAGE }; + + + public LayoutProps() { + breakBefore = breakAfter = Constants.AUTO; + bIsSpan = false; + } + + // public static int higherBreak(int brkParent, int brkChild) { + // if (brkParent == brkChild) return brkChild; + // for (int i=0; i < s_breakPriorities.length; i++) { + // int bp = s_breakPriorities[i]; + // if (bp == brkParent) return brkChild; + // else if (bp == brkChild) return brkParent; + // } + // return brkChild; + // } + + public void combineWithParent(LayoutProps parentLP) { + if (parentLP.breakBefore != breakBefore) { + for (int i = 0; i < BREAK_PRIORITIES.length; i++) { + int bp = BREAK_PRIORITIES[i]; + if (bp == breakBefore) { + breakBefore = parentLP.breakBefore; + break; + } else if (bp == parentLP.breakBefore) { + break; + } + } + } + // Parent span always overrides child span + bIsSpan = parentLP.bIsSpan; + } +} + diff --git a/src/java/org/apache/fop/traits/SpaceVal.java b/src/java/org/apache/fop/traits/SpaceVal.java new file mode 100644 index 000000000..579c56099 --- /dev/null +++ b/src/java/org/apache/fop/traits/SpaceVal.java @@ -0,0 +1,137 @@ +/* + * $Id: SpaceVal.java,v 1.4 2003/03/05 20:38:26 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.traits; + +import org.apache.fop.datatypes.Space; +import org.apache.fop.layoutmgr.MinOptMax; +import org.apache.fop.fo.Property; +import org.apache.fop.fo.properties.Constants; + +/** + * Store a single Space property value in simplified form, with all + * Length values resolved. See section 4.3 in the specs. + */ +public class SpaceVal { + + private final MinOptMax space; + private final boolean bConditional; + private final boolean bForcing; + private final int iPrecedence; // Numeric only, if forcing, set to 0 + + /** + * Constructor for SpaceVal objects based on Space objects. + * @param spaceprop Space object to use + */ + public SpaceVal(Space spaceprop) { + space = new MinOptMax(spaceprop.getMinimum().getLength().getValue(), + spaceprop.getOptimum().getLength().getValue(), + spaceprop.getMaximum().getLength().getValue()); + bConditional = + (spaceprop.getConditionality().getEnum() == Constants.DISCARD); + Property precProp = spaceprop.getPrecedence(); + if (precProp.getNumber() != null) { + iPrecedence = precProp.getNumber().intValue(); + bForcing = false; + } else { + bForcing = (precProp.getEnum() == Constants.FORCE); + iPrecedence = 0; + } + } + + /** + * Constructor for SpaceVal objects based on the full set of properties. + * @param space space to use + * @param bConditional Conditionality value + * @param bForcing Forcing value + * @param iPrecedence Precedence value + */ + public SpaceVal(MinOptMax space, boolean bConditional, + boolean bForcing, int iPrecedence) { + this.space = space; + this.bConditional = bConditional; + this.bForcing = bForcing; + this.iPrecedence = iPrecedence; + } + + /** + * Returns the Conditionality value. + * @return the Conditionality value + */ + public boolean isConditional() { + return bConditional; + } + + /** + * Returns the Forcing value. + * @return the Forcing value + */ + public boolean isForcing() { + return bForcing; + } + + /** + * Returns the Precedence value. + * @return the Precedence value + */ + public int getPrecedence() { + return iPrecedence; + } + + /** + * Returns the Space value. + * @return the Space value + */ + public MinOptMax getSpace() { + return space; + } + +} + diff --git a/src/java/org/apache/fop/util/CharUtilities.java b/src/java/org/apache/fop/util/CharUtilities.java new file mode 100644 index 000000000..d612b9e38 --- /dev/null +++ b/src/java/org/apache/fop/util/CharUtilities.java @@ -0,0 +1,232 @@ +/* + * $Id$ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.util; + +import org.apache.fop.layout.FontState; + +/** + * This class provides utilities to distinguish various kinds of Unicode + * whitespace and to get character widths in a given FontState. + */ +public class CharUtilities { + + /** Character code used to signal a character boundary in + * inline content, such as an inline with borders and padding + * or a nested block object. + */ + public static final char CODE_EOT = 0; + + /** + * Character class: Unicode white space + */ + public static final int UCWHITESPACE = 0; + /** + * Character class: Line feed + */ + public static final int LINEFEED = 1; + /** + * Character class: Boundary between text runs + */ + public static final int EOT = 2; + /** + * Character class: non-whitespace + */ + public static final int NONWHITESPACE = 3; + /** + * Character class: XML whitespace + */ + public static final int XMLWHITESPACE = 4; + + + /** + * Return the appropriate CharClass constant for the type + * of the passed character. + * @param c character to inspect + * @return int the determined character class + */ + public static int classOf(char c) { + if (c == CODE_EOT) { return EOT; } + if (c == '\n') { return LINEFEED; } + if (c == ' ' || c == '\r' || c == '\t') { return XMLWHITESPACE; } + if (isAnySpace(c)) { return UCWHITESPACE; } + return NONWHITESPACE; + } + + /** + * Helper method for getting the width of a unicode char + * from the current fontstate. + * This also performs some guessing on widths on various + * versions of space that might not exists in the font. + * @param c character to inspect + * @param fs FontState to use + * @return int the width of the character + */ + public static int getCharWidth(char c, FontState fs) { + int width; + + if ((c == '\n') || (c == '\r') || (c == '\t') || (c == '\u00A0')) { + width = getCharWidth(' ', fs); + } else { + width = fs.getWidth(fs.mapChar(c)); + if (width <= 0) { + // Estimate the width of spaces not represented in + // the font + int em = fs.getWidth(fs.mapChar('m')); + int en = fs.getWidth(fs.mapChar('n')); + if (em <= 0) { + em = 500 * fs.getFontSize(); + } + if (en <= 0) { + en = em - 10; + } + + if (c == ' ') { + width = em; + } + if (c == '\u2000') { + width = en; + } + if (c == '\u2001') { + width = em; + } + if (c == '\u2002') { + width = em / 2; + } + if (c == '\u2003') { + width = fs.getFontSize(); + } + if (c == '\u2004') { + width = em / 3; + } + if (c == '\u2005') { + width = em / 4; + } + if (c == '\u2006') { + width = em / 6; + } + if (c == '\u2007') { + width = getCharWidth(' ', fs); + } + if (c == '\u2008') { + width = getCharWidth('.', fs); + } + if (c == '\u2009') { + width = em / 5; + } + if (c == '\u200A') { + width = 5; + } + if (c == '\u200B') { + width = 100; + } + if (c == '\u202F') { + width = getCharWidth(' ', fs) / 2; + } + if (c == '\u3000') { + width = getCharWidth(' ', fs) * 2; + } + } + } + + return width; + } + + /** + * Helper method to determine if the character is a + * space with normal behaviour. Normal behaviour means that + * it's not non-breaking. + * @param c character to inspect + * @return boolean True if the character is a normal space + */ + public static boolean isSpace(char c) { + return (c == ' ' + || (c >= '\u2000' && c <= '\u200B')); +// c == '\u2000' // en quad +// c == '\u2001' // em quad +// c == '\u2002' // en space +// c == '\u2003' // em space +// c == '\u2004' // three-per-em space +// c == '\u2005' // four--per-em space +// c == '\u2006' // six-per-em space +// c == '\u2007' // figure space +// c == '\u2008' // punctuation space +// c == '\u2009' // thin space +// c == '\u200A' // hair space +// c == '\u200B' // zero width space + } + + /** + * Method to determine if the character is a nonbreaking + * space. + * @param c character to check + * @return boolean True if the character is a nbsp + */ + public static boolean isNBSP(char c) { + if (c == '\u00A0' || c == '\u202F' // narrow no-break space + || c == '\u3000' // ideographic space + || c == '\uFEFF') { // zero width no-break space + return true; + } else { + return false; + } + } + + /** + * Determines if the character represents any kind of space. + * @param c character to check + * @return True if the character represents any kind of space + */ + public static boolean isAnySpace(char c) { + boolean ret = (isSpace(c) || isNBSP(c)); + return ret; + } +} + diff --git a/src/java/org/apache/fop/util/StreamUtilities.java b/src/java/org/apache/fop/util/StreamUtilities.java new file mode 100644 index 000000000..bf1e17cc6 --- /dev/null +++ b/src/java/org/apache/fop/util/StreamUtilities.java @@ -0,0 +1,243 @@ +/* + * $Id: StreamUtilities.java,v 1.3 2003/03/07 10:09:50 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.util; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.EOFException; +import java.io.DataInput; +import java.io.DataOutput; +import java.util.zip.CRC32; + +/** + * General handy stream i/o methods. + */ +public class StreamUtilities { + + /** + * Size of buffers. Duh. + */ + public static final int BUFFER_SIZE = 4096; // cuz I like big buffers... + + /** + * Binary copies bytes from an input stream to an output stream. + * The process is buffered, so you shouldn't need + * BufferedInput/OutputStreams. Flushes when it's finished, but does + * not close either stream. Returns the number of bytes copied. + * @param source InputStream to read from + * @param sink OutputStream to write to + * @return long the total number of bytes copied + * @throws IOException In case of an I/O problem + */ + public static long streamCopy(InputStream source, + OutputStream sink) throws IOException { + // set table + byte[] buffer = new byte[BUFFER_SIZE]; + long total = 0; + + // trough + int scoop; + while ((scoop = source.read(buffer)) >= 0) { + if (scoop == 0) { + System.out.println("zero scoop!"); + } + sink.write(buffer, 0, scoop); + total += scoop; + } + + // do dishes + sink.flush(); + + return total; + } + + /** + * Method streamCopy. + */ + /** + * Binary copies up to the given number of bytes from an input + * stream to an output stream. The process is buffered, so you + * shouldn't need BufferedInput/OutputStreams. + * Flushes when it's finished, but does not close either stream. + * Throws an EOFExeption if there aren't enough bytes available to + * transfer the requested amount. + * @param source InputStream to read from + * @param sink OutputStream to write to + * @param howMany requested amount of bytes that are to be copied + * @return long the total number of bytes copied + * @throws IOException In case of an I/O problem + */ + public static long streamCopy(InputStream source, + OutputStream sink, int howMany) throws IOException { + // set table + byte[] buffer = new byte[BUFFER_SIZE]; + int left = howMany; + + // trough + int scoop; + while (left > 0) { + scoop = source.read(buffer, 0, Math.min(BUFFER_SIZE, left)); + if (scoop < 0) { + throw new EOFException( + "Not enough bytes to feed you in " + + "IOLib.streamCopy(source, sink, howMany); you asked for " + + howMany + " and I only have " + (howMany - left)); + } + + sink.write(buffer, 0, scoop); + left -= scoop; + } + + // do dishes + sink.flush(); + + return howMany; + } + + /** + * Method streamCopyWithChecksum. + */ + /** + * Binary copies up to the given number of bytes from an input + * stream to an output stream. The process is buffered, so you + * shouldn't need BufferedInput/OutputStreams. + * Flushes when it's finished, but does not close either stream. + * Throws an EOFExeption if there aren't enough bytes available + * to transfer the requested amount. + * @param source InputStream to read from + * @param sink OutputStream to write to + * @param howMany requested amount of bytes that are to be copied + * @return long the checksum of the bytes copied + * @throws IOException In case of an I/O problem + */ + public static long streamCopyWithChecksum(InputStream source, + OutputStream sink, int howMany) throws IOException { + // set table + byte[] buffer = new byte[BUFFER_SIZE]; + int left = howMany; + CRC32 checksummer = new CRC32(); + + // trough + int scoop; + while (left > 0) { + scoop = source.read(buffer, 0, Math.min(BUFFER_SIZE, left)); + if (scoop < 0) { + throw new EOFException("Not enough bytes to feed you in " + + "IOLib.streamCopy(source, sink, howMany)"); + } + + checksummer.update(buffer, 0, scoop); + sink.write(buffer, 0, scoop); + left -= scoop; + } + + // do dishes + sink.flush(); + + return checksummer.getValue(); + } + + /** + * Method dataCopy. + */ + /** + * Binary copies up to the given number of bytes from a DataInput + * object to an DataOutput object. The process is buffered. Since + * DataOutput doesn't support closing or flushing, it does neither. + * @param source DataInput to read from + * @param sink DataOutput to write to + * @param howMany requested amount of bytes that are to be copied + * @return long the total number of bytes copied + * @throws IOException In case of an I/O problem + */ + public static long dataCopy(DataInput source, DataOutput sink, + int howMany) throws IOException { + // set table + byte[] buffer = new byte[BUFFER_SIZE]; + int left = howMany; + + // trough + int scoop; + while (left > 0) { + scoop = Math.min(BUFFER_SIZE, left); + source.readFully(buffer, 0, scoop); + sink.write(buffer, 0, scoop); + left -= scoop; + } + + // do dishes + return howMany; + } + + + /** + * Loads the contents of the InputStream to a byte array. The InputStream + * isn't closed. + * @param in InputStream to read from + * @param initialTargetBufferSize initial number of bytes to allocate + * (expected size to avoid a lot of reallocations) + * @return byte[] the array of bytes requested + * @throws IOException In case of an I/O problem + */ + public static byte[] toByteArray(InputStream in, int initialTargetBufferSize) + throws IOException { + ByteArrayOutputStream baout = new ByteArrayOutputStream(initialTargetBufferSize); + try { + streamCopy(in, baout); + } finally { + baout.close(); + } + return baout.toByteArray(); + } + +} diff --git a/src/java/org/apache/fop/viewer/Command.java b/src/java/org/apache/fop/viewer/Command.java new file mode 100644 index 000000000..2892c2321 --- /dev/null +++ b/src/java/org/apache/fop/viewer/Command.java @@ -0,0 +1,114 @@ +/* + * $Id: Command.java,v 1.9 2003/03/07 10:09:58 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.viewer; + +//Java +import java.awt.event.ActionEvent; +import javax.swing.AbstractAction; +import javax.swing.ImageIcon; +import java.net.URL; + +/** + * This class represents UI-commands, which can be used as menu or toolbar + * items
. + * When the Command object receives action event, that object's + * doit method is invoked. doit method by default + * does nothing and the class customer have to override it to implement + * any action handling logic. + * Originally contributed by: + * Juergen Verwohlt: Juergen.Verwohlt@jcatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jcatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jcatalog.com + */ +public class Command extends AbstractAction { + + private static final String IMAGE_DIR = "Images/"; + + /** + * Creates Command object with a given name and + * sets the name as a tooltip text. No associated icon image. + * @param name of the command + */ + public Command(String name) { + super(name); + putValue(SHORT_DESCRIPTION, name); + } + + /** + * Creates Command object with a given name, the same + * tooltip text and icon image if appropriate image file is found. + * @param name name of the command + * @param iconName name of the icon + */ + public Command(String name, String iconName) { + super(name); + putValue(SHORT_DESCRIPTION, name); + URL url = getClass().getResource(IMAGE_DIR + iconName + ".gif"); + if (url != null) { + putValue(SMALL_ICON, new ImageIcon(url)); + } + } + + /** + * @see java.awt.event.ActionListener#actionPerformed(ActionEvent) + */ + public void actionPerformed(ActionEvent e) { + doit(); + } + + /** + * Action handler, have to be overrided by subclasses. + */ + public void doit() { + //Do nothing + } +} + diff --git a/src/java/org/apache/fop/viewer/GoToPageDialog.java b/src/java/org/apache/fop/viewer/GoToPageDialog.java new file mode 100644 index 000000000..2156393d4 --- /dev/null +++ b/src/java/org/apache/fop/viewer/GoToPageDialog.java @@ -0,0 +1,160 @@ +/* + * $Id: GoToPageDialog.java,v 1.6 2003/03/07 10:09:58 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.viewer; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Go to Page Dialog. + * Originally contributed by: + * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com + */ +public class GoToPageDialog extends JDialog { + + private JTextField pgNbField; + private int pageNumber = -1; + + /** + * Creates modal dialog with a given title, attached to a given frame. + * @param frame Frame to attach to + * @param title dialog title + * @param translator translator for localization + */ + public GoToPageDialog(Frame frame, String title, Translator translator) { + super(frame, title, true); + jbInit(translator); + pack(); + } + + private void jbInit(Translator translator) { + JPanel panel1 = new JPanel(); + GridBagLayout gridBagLayout1 = new GridBagLayout(); + JLabel pgNbLabel = new JLabel(); + pgNbField = new JTextField(); + JButton okButton = new JButton(); + JButton cancelButton = new JButton(); + panel1.setLayout(gridBagLayout1); + pgNbLabel.setText(translator.getString("Label.Page.number")); + okButton.setText(translator.getString("Button.Ok")); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + okButtonActionPerformed(e); + } + }); + cancelButton.setText(translator.getString("Button.Cancel")); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(ActionEvent e) { + cancelButtonActionPerformed(e); + } + }); + panel1.setMinimumSize(new Dimension(250, 78)); + getContentPane().add(panel1); + panel1.add(pgNbLabel, + new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, + GridBagConstraints.NONE, + new Insets(10, 10, 10, 5), 0, 0)); + panel1.add(pgNbField, + new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, + GridBagConstraints.WEST, + GridBagConstraints.BOTH, + new Insets(10, 5, 10, 10), 0, 0)); + panel1.add(okButton, + new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, + GridBagConstraints.EAST, + GridBagConstraints.NONE, + new Insets(0, 0, 10, 5), 0, 0)); + panel1.add(cancelButton, + new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, + GridBagConstraints.NONE, + new Insets(0, 10, 10, 10), 0, 0)); + } + + private void okButtonActionPerformed(ActionEvent e) { + try { + pageNumber = Integer.parseInt(pgNbField.getText()); + dispose(); + } catch (NumberFormatException nfe) { + pgNbField.setText("???"); + } + + } + + private void cancelButtonActionPerformed(ActionEvent e) { + pageNumber = -1; + dispose(); + } + + /** + * Returns page number, entered by user. + * @return the page number + */ + public int getPageNumber() { + return pageNumber; + } +} + diff --git a/src/java/org/apache/fop/viewer/PreviewDialog.java b/src/java/org/apache/fop/viewer/PreviewDialog.java new file mode 100644 index 000000000..9a3ef6cbd --- /dev/null +++ b/src/java/org/apache/fop/viewer/PreviewDialog.java @@ -0,0 +1,587 @@ +/* + * $Id: PreviewDialog.java,v 1.14 2003/03/07 10:09:58 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.viewer; + +//Java +import javax.swing.BorderFactory; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.print.PrinterJob; +import java.awt.print.PrinterException; + +//FOP +import org.apache.fop.apps.AWTStarter; +import org.apache.fop.apps.FOPException; +import org.apache.fop.render.awt.AWTRenderer; + +/** + * AWT Viewer main window. + * Originally contributed by: + * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com + */ +public class PreviewDialog extends JFrame { + + /** The Translator for localization */ + protected Translator translator; + /** The AWT renderer */ + protected AWTRenderer renderer; + /** The AWT starter */ + protected AWTStarter starter; + + private int currentPage = 0; + private int pageCount = 0; + private Reloader reloader; + private JComboBox scale; + private JLabel processStatus; + private JLabel pageLabel; + private JLabel infoStatus; + + /** + * Creates a new PreviewDialog that uses the given starter, renderer and translator. + * @param aStarter the to use starter + * @param aRenderer the to use renderer + * @param aRes the to use translator + */ + public PreviewDialog(AWTStarter aStarter, AWTRenderer aRenderer, Translator aRes) { + this(aRenderer, aRes); + starter = aStarter; + } + + /** + * Creates a new PreviewDialog that uses the given renderer and translator. + * @param aRenderer the to use renderer + * @param aRes the to use translator + */ + public PreviewDialog(AWTRenderer aRenderer, Translator aRes) { + translator = aRes; + renderer = aRenderer; + + //Commands aka Actions + Command printAction = new Command(translator.getString("Menu.Print"), "Print") { + public void doit() { + print(); + } + }; + Command firstPageAction = new Command(translator.getString("Menu.First.page"), + "firstpg") { + public void doit() { + goToFirstPage(); + } + }; + Command previousPageAction = new Command(translator.getString("Menu.Prev.page"), + "prevpg") { + public void doit() { + goToPreviousPage(); + } + }; + Command nextPageAction = new Command(translator.getString("Menu.Next.page"), "nextpg") { + public void doit() { + goToNextPage(); + } + + }; + Command lastPageAction = new Command(translator.getString("Menu.Last.page"), "lastpg") { + public void doit() { + goToLastPage(); + } + }; + Command reloadAction = new Command(translator.getString("Menu.Reload"), "reload") { + public void doit() { + reload(); + } + }; + + setTitle("FOP: AWT-" + translator.getString("Title.Preview")); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + //Sets size to be 61%x90% of the screen size + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + //Rather frivolous size - fits A4 page width in 1024x768 screen on my desktop + setSize(screen.width * 61 / 100, screen.height * 9 / 10); + + //Page view stuff + pageLabel = new JLabel(); + JScrollPane previewArea = new JScrollPane(pageLabel); + previewArea.getViewport().setBackground(Color.gray); + previewArea.setMinimumSize(new Dimension(50, 50)); + getContentPane().add(previewArea, BorderLayout.CENTER); + + //Scaling combobox + scale = new JComboBox(); + scale.addItem("25%"); + scale.addItem("50%"); + scale.addItem("75%"); + scale.addItem("100%"); + scale.addItem("150%"); + scale.addItem("200%"); + scale.setMaximumSize(new Dimension(80, 24)); + scale.setPreferredSize(new Dimension(80, 24)); + scale.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + scaleActionPerformed(e); + } + }); + scale.setSelectedItem("100%"); + renderer.setScaleFactor(100.0); + + //Menu + setJMenuBar(setupMenu()); + + //Toolbar + JToolBar toolBar = new JToolBar(); + toolBar.add(printAction); + toolBar.add(reloadAction); + toolBar.addSeparator(); + toolBar.add(firstPageAction); + toolBar.add(previousPageAction); + toolBar.add(nextPageAction); + toolBar.add(lastPageAction); + toolBar.addSeparator(); + toolBar.add(new JLabel(translator.getString("Menu.Zoom"))); + toolBar.addSeparator(); + toolBar.add(scale); + getContentPane().add(toolBar, BorderLayout.NORTH); + //Status bar + JPanel statusBar = new JPanel(); + processStatus = new JLabel(); + processStatus.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(), + BorderFactory.createEmptyBorder(0, 3, 0, 0))); + infoStatus = new JLabel(); + infoStatus.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEtchedBorder(), + BorderFactory.createEmptyBorder(0, 3, 0, 0))); + + statusBar.setLayout(new GridBagLayout()); + + processStatus.setPreferredSize(new Dimension(200, 21)); + processStatus.setMinimumSize(new Dimension(200, 21)); + + infoStatus.setPreferredSize(new Dimension(100, 21)); + infoStatus.setMinimumSize(new Dimension(100, 21)); + statusBar.add(processStatus, + new GridBagConstraints(0, 0, 1, 0, 2.0, 0.0, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 3), 0, 0)); + statusBar.add(infoStatus, + new GridBagConstraints(1, 0, 1, 0, 1.0, 0.0, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(0, 0, 0, 0), 0, 0)); + getContentPane().add(statusBar, BorderLayout.SOUTH); + } + + /** + * Creates a new menubar to be shown in this window. + * @return the newly created menubar + */ + private JMenuBar setupMenu() { + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu(translator.getString("Menu.File")); + + //Adds mostly the same actions, but without icons + menu.add(new Command(translator.getString("Menu.Print")) { + public void doit() { + print(); + } + }); + menu.add(new Command(translator.getString("Menu.Reload")) { + public void doit() { + reload(); + } + }); + menu.addSeparator(); + menu.add(new Command(translator.getString("Menu.Exit")) { + public void doit() { + dispose(); + } + }); + menuBar.add(menu); + menu = new JMenu(translator.getString("Menu.View")); + menu.add(new Command(translator.getString("Menu.First.page")) { + public void doit() { + goToFirstPage(); + } + }); + menu.add(new Command(translator.getString("Menu.Prev.page")) { + public void doit() { + goToPreviousPage(); + } + }); + menu.add(new Command(translator.getString("Menu.Next.page")) { + public void doit() { + goToNextPage(); + } + }); + menu.add(new Command(translator.getString("Menu.Last.page")) { + public void doit() { + goToLastPage(); + } + }); + menu.add(new Command(translator.getString("Menu.Go.to.Page") + " ...") { + public void doit() { + showGoToPageDialog(); + } + }); + menu.addSeparator(); + JMenu subMenu = new JMenu(translator.getString("Menu.Zoom")); + subMenu.add(new Command("25%") { + public void doit() { + setScale(25.0); + } + }); + subMenu.add(new Command("50%") { + public void doit() { + setScale(50.0); + } + }); + subMenu.add(new Command("75%") { + public void doit() { + setScale(75.0); + } + }); + subMenu.add(new Command("100%") { + public void doit() { + setScale(100.0); + } + }); + subMenu.add(new Command("150%") { + public void doit() { + setScale(150.0); + } + }); + subMenu.add(new Command("200%") { + public void doit() { + setScale(200.0); + } + }); + menu.add(subMenu); + menu.addSeparator(); + menu.add(new Command(translator.getString("Menu.Default.zoom")) { + public void doit() { + setScale(100.0); + } + }); + menuBar.add(menu); + menu = new JMenu(translator.getString("Menu.Help")); + menu.add(new Command(translator.getString("Menu.About")) { + public void doit() { + startHelpAbout(); + } + }); + menuBar.add(menu); + return menuBar; + } + + /** + * Shows the About box + */ + private void startHelpAbout() { + PreviewDialogAboutBox dlg = new PreviewDialogAboutBox(this, translator); + //Centers the box + Dimension dlgSize = dlg.getPreferredSize(); + Dimension frmSize = getSize(); + Point loc = getLocation(); + dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, + (frmSize.height - dlgSize.height) / 2 + loc.y); + dlg.setVisible(true); + } + + /** + * Changes the current visible page + * @param number the page number to go to + */ + private void goToPage(int number) { + currentPage = number; + renderer.setPageNumber(number); + showPage(); + } + + /** + * Shows the previous page. + */ + private void goToPreviousPage() { + if (currentPage <= 0) { + return; + } + currentPage--; + goToPage(currentPage); + } + + + /** + * Shows the next page. + */ + private void goToNextPage() { + if (currentPage >= pageCount - 1) { + return; + } + currentPage++; + goToPage(currentPage); + } + + /** + * Shows the last page. + */ + private void goToLastPage() { + if (currentPage == pageCount - 1) { + return; + } + currentPage = pageCount - 1; + goToPage(currentPage); + } + + /** + * Reloads and reformats document. + */ + private synchronized void reload() { + if (reloader == null || !reloader.isAlive()) { + reloader = new Reloader(); + reloader.start(); + } + } + + /** + * This class is used to reload document in + * a thread safe way. + */ + private class Reloader extends Thread { + public void run() { + pageLabel.setIcon(null); + infoStatus.setText(""); + currentPage = 0; + //Cleans up renderer - to be done + //while (renderer.getPageCount() != 0) + // renderer.removePage(0); + try { + starter.run(); + } catch (FOPException e) { + reportException(e); + } + } + } + + /** + * Shows "go to page" dialog and then goes to the selected page + */ + private void showGoToPageDialog() { + GoToPageDialog d = new GoToPageDialog(this, + translator.getString("Menu.Go.to.Page"), translator); + d.setLocation((int)getLocation().getX() + 50, + (int)getLocation().getY() + 50); + d.setVisible(true); + currentPage = d.getPageNumber(); + if (currentPage < 1 || currentPage > pageCount) { + return; + } + currentPage--; + goToPage(currentPage); + } + + /** + * Shows the first page. + */ + private void goToFirstPage() { + if (currentPage == 0) { + return; + } + currentPage = 0; + goToPage(currentPage); + } + + /** + * Prints the document + */ + private void print() { + PrinterJob pj = PrinterJob.getPrinterJob(); + pj.setPageable(renderer); + if (pj.printDialog()) { + try { + pj.print(); + } catch (PrinterException pe) { + pe.printStackTrace(); + } + } + } + + /** + * Scales page image + */ + private void setScale(double scaleFactor) { + if (scaleFactor == 25.0) { + scale.setSelectedIndex(0); + } else if (scaleFactor == 50.0) { + scale.setSelectedIndex(1); + } else if (scaleFactor == 75.0) { + scale.setSelectedIndex(2); + } else if (scaleFactor == 100.0) { + scale.setSelectedIndex(3); + } else if (scaleFactor == 150.0) { + scale.setSelectedIndex(4); + } else if (scaleFactor == 200.0) { + scale.setSelectedIndex(5); + } + renderer.setScaleFactor(scaleFactor); + showPage(); + } + + private void scaleActionPerformed(ActionEvent e) { + String item = (String)scale.getSelectedItem(); + setScale(Double.parseDouble(item.substring(0, item.indexOf('%')))); + } + + /** + * Sets message to be shown in the status bar in a thread safe way. + * @param message the message + */ + public void setStatus(String message) { + SwingUtilities.invokeLater(new ShowStatus(message)); + } + + /** + * This class is used to show status in a thread safe way. + */ + private class ShowStatus implements Runnable { + /** + * The message to display + */ + private String message; + /** + * Constructs ShowStatus thread + * @param message message to display + */ + public ShowStatus(String message) { + this.message = message; + } + + public void run() { + processStatus.setText(message.toString()); + } + } + + /** + * Starts rendering process and shows the current page. + */ + public void showPage() { + ShowPageImage viewer = new ShowPageImage(); + if (SwingUtilities.isEventDispatchThread()) { + viewer.run(); + } else { + SwingUtilities.invokeLater(viewer); + } + } + + + /** + * This class is used to update the page image + * in a thread safe way. + */ + private class ShowPageImage implements Runnable { + /** + * The run method that does the actual updating + */ + public void run() { + //Rendering a page - to be done + /* + renderer.render(currentPage); + BufferedImage pageImage = renderer.getLastRenderedPage(); + if (pageImage == null) + return; + pageLabel.setIcon(new ImageIcon(pageImage)); + pageCount = renderer.getPageCount(); + //Updates status bar + infoStatus.setText(translator.getString("Status.Page") + " " + + (currentPage + 1) + " " + + translator.getString("Status.of") + " " + pageCount); + */ + } + } + + /** + * Opens standard Swing error dialog box and reports given exception details. + * @param e the Exception + */ + public void reportException(Exception e) { + String msg = translator.getString("Exception.Occured"); + setStatus(msg); + JOptionPane.showMessageDialog( + getContentPane(), + "" + msg + ":
" + + e.getClass().getName() + "
" + + e.getMessage() + "", + translator.getString("Exception.Error"), + JOptionPane.ERROR_MESSAGE + ); + } +} + diff --git a/src/java/org/apache/fop/viewer/PreviewDialogAboutBox.java b/src/java/org/apache/fop/viewer/PreviewDialogAboutBox.java new file mode 100644 index 000000000..557db5531 --- /dev/null +++ b/src/java/org/apache/fop/viewer/PreviewDialogAboutBox.java @@ -0,0 +1,150 @@ +/* + * $Id: PreviewDialogAboutBox.java,v 1.5 2003/03/07 10:09:58 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.viewer; + +//Java +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.GridLayout; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.ActionEvent; + +//FOP +import org.apache.fop.apps.Version; + +/** + * AWT Viewer's "About" dialog. + * Originally contributed by: + * Juergen Verwohlt: Juergen.Verwohlt@jCatalog.com, + * Rainer Steinkuhle: Rainer.Steinkuhle@jCatalog.com, + * Stanislav Gorkhover: Stanislav.Gorkhover@jCatalog.com + */ +public class PreviewDialogAboutBox extends Dialog implements ActionListener { + private JButton okButton; + + /** + * Creates modal "About" dialog, attached to a given parent frame. + * @param parent parent frame + * @param translator Translator for localization + */ + public PreviewDialogAboutBox(Frame parent, Translator translator) { + super(parent, true); + enableEvents(AWTEvent.WINDOW_EVENT_MASK); + setTitle(translator.getString("About.Title")); + setResizable(false); + JPanel panel1 = new JPanel(); + JPanel panel2 = new JPanel(); + JPanel insetsPanel1 = new JPanel(); + JPanel insetsPanel2 = new JPanel(); + JPanel insetsPanel3 = new JPanel(); + okButton = new JButton(); + JLabel imageControl1 = new JLabel(); + imageControl1.setIcon(new ImageIcon(getClass().getResource("Images/fop.gif"))); + JLabel label1 = new JLabel(translator.getString("About.Product")); + JLabel label2 = new JLabel(translator.getString("About.Version") + + " " + Version.getVersion()); + JLabel label3 = new JLabel(translator.getString("About.Copyright")); + panel1.setLayout(new BorderLayout()); + panel2.setLayout(new BorderLayout()); + insetsPanel1.setLayout(new FlowLayout()); + insetsPanel2.setLayout(new FlowLayout()); + insetsPanel2.setBorder(new EmptyBorder(10, 10, 10, 10)); + insetsPanel3.setLayout(new GridLayout(3, 1)); + insetsPanel3.setBorder(new EmptyBorder(10, 10, 10, 10)); + okButton.setText(translator.getString("Button.Ok")); + okButton.addActionListener(this); + insetsPanel2.add(imageControl1, null); + panel2.add(insetsPanel2, BorderLayout.WEST); + insetsPanel3.add(label1); + insetsPanel3.add(label2); + insetsPanel3.add(label3); + panel2.add(insetsPanel3, BorderLayout.CENTER); + insetsPanel1.add(okButton); + panel1.add(insetsPanel1, BorderLayout.SOUTH); + panel1.add(panel2, BorderLayout.NORTH); + add(panel1); + pack(); + } + + /** + * @see java.awt.Window#processWindowEvent(WindowEvent) + */ + protected void processWindowEvent(WindowEvent e) { + if (e.getID() == WindowEvent.WINDOW_CLOSING) { + cancel(); + } + super.processWindowEvent(e); + } + + private void cancel() { + dispose(); + } + + /** + * @see java.awt.event.ActionListener#actionPerformed(ActionEvent) + */ + public void actionPerformed(ActionEvent e) { + if (e.getSource() == okButton) { + cancel(); + } + } +} + diff --git a/src/java/org/apache/fop/viewer/Translator.java b/src/java/org/apache/fop/viewer/Translator.java new file mode 100644 index 000000000..2381dc1eb --- /dev/null +++ b/src/java/org/apache/fop/viewer/Translator.java @@ -0,0 +1,91 @@ +/* + * $Id: Translator.java,v 1.6 2003/03/07 10:09:58 jeremias Exp $ + * ============================================================================ + * The Apache Software License, Version 1.1 + * ============================================================================ + * + * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: "This product includes software + * developed by the Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "FOP" and "Apache Software Foundation" must not be used to + * endorse or promote products derived from this software without prior + * written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", nor may + * "Apache" appear in their name, without prior written permission of the + * Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- + * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ============================================================================ + * + * This software consists of voluntary contributions made by many individuals + * on behalf of the Apache Software Foundation and was originally created by + * James Tauber . For more information on the Apache + * Software Foundation, please see . + */ +package org.apache.fop.viewer; + +//Java +import java.util.ResourceBundle; +import java.util.Locale; + +/** + * AWT Viewer's localization class, backed up by java.util.ResourceBundle. + * Originally contributed by: + * Stanislav.Gorkhover@jCatalog.com + */ +public class Translator { + + private ResourceBundle bundle; + private static String bundleBaseName = "org/apache/fop/viewer/resources/Viewer"; + + /** + * Default constructor, default Locale is used. + */ + public Translator() { + this(Locale.getDefault()); + } + + /** + * Constructor for a given Locale. + * @param locale Locale to use + */ + public Translator(Locale locale) { + bundle = ResourceBundle.getBundle(bundleBaseName, locale); + } + + /** + * Returns localized String for a given key. + * @param key the key + * @return the localized String + */ + public String getString(String key) { + return bundle.getString(key); + } +} + diff --git a/src/java/org/apache/fop/viewer/images/Print.gif b/src/java/org/apache/fop/viewer/images/Print.gif new file mode 100644 index 0000000000000000000000000000000000000000..e715fe67f5f3d1bcbe5d5c5d3f386cdb3d6c5d10 GIT binary patch literal 992 zcmXX_Pe_z;5S>(Lvq*)M4U$SFN<5g;!RXLJrs*LOTDnxwWekE29<;#2ia}ywK^+>x zaQj1M9YP}l6O`;wPDv0!&|ZW(6fC4cc$(gPxG?+u=9}NVdGF0`M`wHM;qz%q(?5z& z4xji&Y&>%DE<>3N<(x7&d4&7?{Jawmh>eHG>m2GiJP>HeWs1dOp-?ch+1c5tsVP+* z85tQE7!Z+cHrv+L#>{nfbyZbW?&hxU;?8k2b5l2QLrPImb5&PyWmk%eVlL_;F6=_+ zb2evn7H4(_HFHuYaY6y800j!#kWx%AH4`&7qnL(F)l^K`lwvrFq9$U(CKOz7m(^H| z*_c2Ltww4jhAD)3APX>X1v#)m4O4*)Xkek4LPzAH%BmEaFcX=G3ad~^1O*gXlv$ae z7>saNNt9R#s^9@Qq8k=KGZ;V{C<6?PK@nF$0#ktvXkbye6=mcsLg5^gVJ0$WVS`%5+*^P>_Q3dM=BHFuNwuxvvHQ^op5oyY#=BPHc>%@zRh2hfd{xg%6x48G=YHNLKdDs2xX+AfY z`n+@W+UERZWoKVQ&DD~Q<8LOXA20P(bmVuW_vE_9DtZRDHP1Zh9xBhLs-Lbr>dx2S z9$hTyd9W~gEI)X+@zCmR>yP)_#Vto<_B`Fiz-9WA~5 L_g=qbh>rXR0$R@L literal 0 HcmV?d00001 diff --git a/src/java/org/apache/fop/viewer/images/firstpg.gif b/src/java/org/apache/fop/viewer/images/firstpg.gif new file mode 100644 index 0000000000000000000000000000000000000000..1d0315d749b6b2e49c93d3b7d088d193cbb5e5f5 GIT binary patch literal 885 zcmV-*1B(1dNk%w1VHf}y0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW00930EC2ui02lxm06+**0RIUbNU)&6g8~5nD5!8DLWT|rDtt(> zBEpIP8aA}Zv7^U}5hZrSm{H@%kS0H>T*^nO<{{H^z>gh5vGO4`F(9qDbqn!5k_PgfJ zRa8_&LqnE`h|bQ=wy>o9{QUX(`HPX4Vp?0()z!_bu61>Fq^6@vR7ubB&~k}!a9m!S zo14|TyKHW4-rnBhzq97T!O5+xz@(hgzOQ0yanQN7z{tO=o9kh@ghc-tfZI<8OX&Q%gz0 zte0otTHVv zOHfoPA|ft2F3`!#XklXN>F24hz2LpPTV!piv!+^9RzEH+M2JLpU%sdUJIn zDk8kKwY0Xk*2J*=|No@HqR7a|r@Excw7oVtKTAtUVq#-RNl6NPes=H}*5Pfs{FI43A5MLIeyGcZ9xKrSvXKSDzh5fRPH%*V&a zR$pF=iioVitxG^a@bK@dwX2twmV1wtRa00_S6^6HS2Q;|QfE_eaC1L4IJ>&L3knO> z)Y1L@{jb)pqraZd%gWEq%f#2~$l2&^d4%WZ=jZC?*|WLFqo&HPqsFqM!^q3i)6>+^ z(vW|9&Bw>h#>g%wC@L%{n!>5(#mMc)$AyK4g^rGihlP}%sEme*;J?ALs;0oGrjMhT z(e==HczL6&pQxy(sHmj-|Nf?tj{W`m)4;%^#joz}?WoJDX=!O;WMyPzWM*Y!ox7)N zXJ@Ow!~g&PA^8LV00000EC2ui09pVZ000R80RIUbNU)&6ffOhdRHiVK!-oe6QV0>z zU_yZxD{4HbaAQOYF&y05L~;|iX3m`1TB-6-H*Lx?A@oSIrbJ$wZhgpBqC_?fwr-ti za?FX7V@+U)_*Wto9XD>C0{VkyABn4!JOJu+jDpO631JXza>l`#p~s3|a&ilX51Sel z-kK$A!m9uQNWHSKYLx{GvtHH8G45>%OKa%RDZ;{-x5wUQ4T3<#o1-#sG5+hZmk6>P z$ZC-y^6C`?%0yb>V5JN$M`<_=ya?4nFoaREI&_fbDuFO$Jb3+MgTRt6S$JPf0OJUW zumrk01VHwJ4Z#mB${=Yqib#M}!d?{r+tTV&f&e*$WozwPV!{v~WEH#X>w|p^n=a+z z5TMM`5@!@qNM5^aqmBzwEMmqK@~{940J7vT!7&v`kcd5zNK-~AFVr#%3T&`aK@2ps z^T`Poa@&{D(q&mPDQ2gM>tAHT?GK!ly6tjl{U0`7Vqd5Rjfk7c~AWSPcoM7pt17+$V zr<#GK!BP$cKq!P!qaimkmA7iv(MjL_PKuA8qd2UgWxKqX0+%mPEr6+QYHP z{-f-s1Sz9|Eo@Nq&kGQ&g3LDIFdPy7JntK_Vp3 zieT^fTkpMWURO(S|JY+e0;G^4Pr-QNDUJ!RzFG&w{&-T%DmhrO#|0T9(W^ZMu>k?G z30POJK=;y6kPbP#;BGdr08mRM9*prr8jEzjNHr#yB6c0&`ZLNFq4X?=x*EGnPza#7 z(y|WpjywSXd7aS0-o6Iy71B6$prd1Y-aL z139m=6Z702ng=&=80W2;zuG%s>Q|m;p6_Us{f@gHWg+c>>_HI~_dvWR_ zO@M#_mZE_KAR%o4fX5Ly!3<6e!2sh3!U%#81ai~>96*SLBRr&t1uVdY>_QzE58}mw z_}~LF@D~q4(T^N-;0#e{00A1X18nf)l9*J&29{6>CozHnegtH%1UX1d`12+!gmP1&_0SxG`2-!YUW;>@W=;(n6_3dg8&2&fB^16PkJUH z30g2jEn+eM0vq_#1_&s}D%kZab7IOBczeYeHjPh7s*J3G^7y;3E;p2jS>cn49bvyD8m*I*n(hCu#^xmP$K`B2M&e-j0Ehn2fEmS zJO%IoE`$OCmCyn$g+mZu%mN>^a0LdGp$wZ2G9hf(0zNo!zz!h80>S{m2X1PRc{HJV zviJrmDj|s!q#yyVAVMX`u!3c%APTAg3kpDikLdxx0^j4n31mRlr77eC2{4Z=W-$xC zSb!7=5Sc+vaf*Lr;{_=&L@ZuGgi?KD6)9MOCIkS_0u;0i9gv1{w1ex(fHRs_5THB$w25QPHx S_rLz_ZxjTK08*ARAOJfmQhBQY literal 0 HcmV?d00001 diff --git a/src/java/org/apache/fop/viewer/images/lastpg.gif b/src/java/org/apache/fop/viewer/images/lastpg.gif new file mode 100644 index 0000000000000000000000000000000000000000..082f13a26fe54d61ae7cfe2d52ffbe629ae519c8 GIT binary patch literal 889 zcmV-<1BU!ZNk%w1VHf}y0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW006xJEC2ui02lxm06+*<0DB1>NU)&6g98C51VB(BLW2w;Mtn%I zqQr#>CtBRdv137pA2m{3h_M$)izPF9T*6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW006xJEC2ui02lxm06+*r0DB1>NU)&6g9QO7M97ff!iEqdMpQ@< vfW(U!Ga|I8F=54yy*`2*NwTELlMNq^6xp$&N{lW+QY6U{rOlfL0|Ed$6HT6| literal 0 HcmV?d00001 diff --git a/src/java/org/apache/fop/viewer/images/prevpg.gif b/src/java/org/apache/fop/viewer/images/prevpg.gif new file mode 100644 index 0000000000000000000000000000000000000000..3c8cce4b60d5c4c759888928534a1d8c70d446b0 GIT binary patch literal 867 zcmV-p1DyOvNk%w1VHf}y0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW006xJEC2ui02lxm06+*p0DB1>NU)&6g9ia9M98qPmNwTELlOrF7q_|RKOO-88f<#HPCc%IJ06WFzox1=4 literal 0 HcmV?d00001 diff --git a/src/java/org/apache/fop/viewer/images/reload.gif b/src/java/org/apache/fop/viewer/images/reload.gif new file mode 100644 index 0000000000000000000000000000000000000000..405718c1bb03d617c9796f5e833e1aa6893ed9c7 GIT binary patch literal 889 zcmV-<1BU!ZNk%w1VHf}y0QUd@000010RaL60s{jB1Ox;H1qB8M1_uWR2nYxX2?+`c z3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH8XFrM z92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7 zEiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}? zK0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuy zP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?Wj zVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2T za&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyD zgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z} zm6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5( zrl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#p zxVX5vxw*Q!y1To(yu7@dCU$jHda z$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4 z?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg= z{r&#_{{R2~A^8LW006xJEC2ui02lxm06+*<0DB1>NU)&6g8&jLOgNC?L4ytjE{yoF zqD6=RFkalqvE#*s1u0q-*^A^uk|q&m47t*y%a<@=qHI}lBF&T