From dece1d7361bfe21604222d1dbfdc1b599084a363 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 4 Apr 2006 15:15:23 +0000 Subject: [PATCH] Adding dependency on XML Graphics Commons. Switching to code in XML Graphics Commons for: - PSGraphics2D - Service discovery - Codecs Removed local classes that have been ported to Commons. xmlgraphics-commons-snapshot.jar is a Trunk snapshot built with JDK 1.4.2 from today. It should work under JDK 1.3.1. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@391332 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 8 +- lib/README.txt | 8 + lib/xmlgraphics-commons-snapshot.jar | Bin 0 -> 256033 bytes lib/xmlgraphics-commons.LICENSE.txt | 202 +++ lib/xmlgraphics-commons.NOTICE.txt | 2 + .../apache/fop/fo/ElementMappingRegistry.java | 14 +- src/java/org/apache/fop/image/PNGImage.java | 19 +- src/java/org/apache/fop/image/TIFFImage.java | 23 +- ...mage.java => XmlGraphicsCommonsImage.java} | 85 +- .../org/apache/fop/pdf/ASCII85Filter.java | 2 +- .../org/apache/fop/pdf/ASCIIHexFilter.java | 2 +- src/java/org/apache/fop/pdf/FlateFilter.java | 4 +- .../apache/fop/render/RendererFactory.java | 19 +- .../apache/fop/render/XMLHandlerRegistry.java | 9 +- .../apache/fop/render/bitmap/PNGRenderer.java | 26 +- .../render/bitmap/PNGRenderer_onthefly.java | 8 +- .../fop/render/bitmap/TIFFRenderer.java | 14 +- .../ps/AbstractPSDocumentGraphics2D.java | 263 ---- .../fop/render/ps/AbstractPSTranscoder.java | 51 +- .../apache/fop/render/ps/DSCConstants.java | 219 --- .../fop/render/ps/EPSDocumentGraphics2D.java | 94 -- .../apache/fop/render/ps/EPSTranscoder.java | 7 +- .../fop/render/ps/NativeTextHandler.java | 190 +++ .../fop/render/ps/PSDocumentGraphics2D.java | 157 --- .../org/apache/fop/render/ps/PSFontUtils.java | 85 +- .../org/apache/fop/render/ps/PSGenerator.java | 600 --------- .../apache/fop/render/ps/PSGraphics2D.java | 1181 ----------------- .../fop/render/ps/PSGraphics2DAdapter.java | 6 +- .../apache/fop/render/ps/PSImageUtils.java | 241 +--- .../org/apache/fop/render/ps/PSProcSets.java | 208 --- .../org/apache/fop/render/ps/PSRenderer.java | 6 + .../org/apache/fop/render/ps/PSResource.java | 63 - .../apache/fop/render/ps/PSSVGHandler.java | 15 +- .../org/apache/fop/render/ps/PSState.java | 201 --- .../apache/fop/render/ps/PSTextPainter.java | 38 +- .../apache/fop/render/ps/PSTranscoder.java | 4 +- .../org/apache/fop/util/ASCII85Constants.java | 58 - .../apache/fop/util/ASCII85InputStream.java | 161 --- .../apache/fop/util/ASCII85OutputStream.java | 220 --- .../apache/fop/util/ASCIIHexOutputStream.java | 102 -- .../util/ContentHandlerFactoryRegistry.java | 9 +- src/java/org/apache/fop/util/Finalizable.java | 42 - .../fop/util/FlateEncodeOutputStream.java | 53 - .../fop/util/RunLengthEncodeOutputStream.java | 186 --- src/java/org/apache/fop/util/Service.java | 113 -- .../org/apache/fop/util/SubInputStream.java | 92 -- .../org/apache/fop/UtilityCodeTestSuite.java | 4 - .../fop/util/ASCII85InputStreamTestCase.java | 165 --- .../fop/util/ASCII85OutputStreamTestCase.java | 101 -- 49 files changed, 620 insertions(+), 4760 deletions(-) create mode 100644 lib/xmlgraphics-commons-snapshot.jar create mode 100644 lib/xmlgraphics-commons.LICENSE.txt create mode 100644 lib/xmlgraphics-commons.NOTICE.txt rename src/java/org/apache/fop/image/{BatikImage.java => XmlGraphicsCommonsImage.java} (74%) delete mode 100644 src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java delete mode 100644 src/java/org/apache/fop/render/ps/DSCConstants.java delete mode 100644 src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java create mode 100644 src/java/org/apache/fop/render/ps/NativeTextHandler.java delete mode 100644 src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java delete mode 100644 src/java/org/apache/fop/render/ps/PSGenerator.java delete mode 100644 src/java/org/apache/fop/render/ps/PSGraphics2D.java delete mode 100644 src/java/org/apache/fop/render/ps/PSProcSets.java delete mode 100644 src/java/org/apache/fop/render/ps/PSResource.java delete mode 100644 src/java/org/apache/fop/render/ps/PSState.java delete mode 100644 src/java/org/apache/fop/util/ASCII85Constants.java delete mode 100644 src/java/org/apache/fop/util/ASCII85InputStream.java delete mode 100644 src/java/org/apache/fop/util/ASCII85OutputStream.java delete mode 100644 src/java/org/apache/fop/util/ASCIIHexOutputStream.java delete mode 100644 src/java/org/apache/fop/util/Finalizable.java delete mode 100644 src/java/org/apache/fop/util/FlateEncodeOutputStream.java delete mode 100644 src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java delete mode 100644 src/java/org/apache/fop/util/Service.java delete mode 100644 src/java/org/apache/fop/util/SubInputStream.java delete mode 100644 test/java/org/apache/fop/util/ASCII85InputStreamTestCase.java delete mode 100644 test/java/org/apache/fop/util/ASCII85OutputStreamTestCase.java diff --git a/build.xml b/build.xml index dcbd533f3..e89fad850 100644 --- a/build.xml +++ b/build.xml @@ -75,6 +75,7 @@ list of possible build targets. + @@ -581,7 +582,7 @@ list of possible build targets. - + @@ -626,6 +627,11 @@ list of possible build targets. + + + + + diff --git a/lib/README.txt b/lib/README.txt index f46c4f05a..88993f656 100644 --- a/lib/README.txt +++ b/lib/README.txt @@ -35,6 +35,14 @@ Normal Dependencies Apache License v2.0 +- Apache XML Graphics Commons + + xmlgraphics-commons-*.jar + http://xmlgraphics.apache.org/ + (Common Library for Apache Batik and Apache FOP) + + Apache License v2.0 + - Apache Batik batik-*.jar diff --git a/lib/xmlgraphics-commons-snapshot.jar b/lib/xmlgraphics-commons-snapshot.jar new file mode 100644 index 0000000000000000000000000000000000000000..dac07e48a7094e9744dc3c7b746e50985727225a GIT binary patch literal 256033 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
R&LGi*&23y?w^ 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%0D6YD&1JDE%1#Pvv7>*%clnpC2CW6_p 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

i7>zw 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

UjkK(%GR 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

  • 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 literal 0 HcmV?d00001 diff --git a/lib/xmlgraphics-commons.LICENSE.txt b/lib/xmlgraphics-commons.LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/lib/xmlgraphics-commons.LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/lib/xmlgraphics-commons.NOTICE.txt b/lib/xmlgraphics-commons.NOTICE.txt new file mode 100644 index 000000000..7196130f7 --- /dev/null +++ b/lib/xmlgraphics-commons.NOTICE.txt @@ -0,0 +1,2 @@ +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/src/java/org/apache/fop/fo/ElementMappingRegistry.java b/src/java/org/apache/fop/fo/ElementMappingRegistry.java index 3636500e0..8ab5a3d98 100644 --- a/src/java/org/apache/fop/fo/ElementMappingRegistry.java +++ b/src/java/org/apache/fop/fo/ElementMappingRegistry.java @@ -19,17 +19,19 @@ package org.apache.fop.fo; import java.util.Iterator; -import java.util.List; import java.util.Map; +import org.w3c.dom.DOMImplementation; +import org.xml.sax.Locator; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.util.Service; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.fo.ElementMapping.Maker; -import org.apache.fop.util.Service; -import org.w3c.dom.DOMImplementation; -import org.xml.sax.Locator; /** * This class keeps track of all configured ElementMapping implementations which are responsible @@ -69,9 +71,9 @@ public class ElementMappingRegistry { Iterator providers = Service.providers(ElementMapping.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + ElementMapping mapping = (ElementMapping)providers.next(); try { - addElementMapping(str); + addElementMapping(mapping); } catch (IllegalArgumentException e) { log.warn("Error while adding element mapping", e); } diff --git a/src/java/org/apache/fop/image/PNGImage.java b/src/java/org/apache/fop/image/PNGImage.java index 6cf50d47c..43cfbe97f 100644 --- a/src/java/org/apache/fop/image/PNGImage.java +++ b/src/java/org/apache/fop/image/PNGImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,13 @@ package org.apache.fop.image; -import java.awt.color.ColorSpace; -import java.awt.color.ICC_Profile; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.PNGRed; -import org.apache.batik.ext.awt.image.codec.PNGDecodeParam; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.codec.png.PNGRed; +import org.apache.xmlgraphics.image.codec.png.PNGDecodeParam; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.rendered.CachableRed; import org.apache.commons.io.IOUtils; -import org.apache.fop.util.CMYKColorSpace; /** * FopImage object using PNG @@ -36,7 +32,7 @@ import org.apache.fop.util.CMYKColorSpace; * @see AbstractFopImage * @see FopImage */ -public class PNGImage extends BatikImage { +public class PNGImage extends XmlGraphicsCommonsImage { /** * Constructs a new PNGImage instance. @@ -48,7 +44,8 @@ public class PNGImage extends BatikImage { } /** - * @see org.apache.fop.image.BatikImage#decodeImage(org.apache.batik.ext.awt.image.codec.SeekableStream) + * @see org.apache.fop.image.XmlGraphicsCommonsImage#decodeImage( + * org.apache.xmlgraphics.image.codec.util.SeekableStream) */ protected CachableRed decodeImage(SeekableStream stream) throws IOException { PNGDecodeParam param = new PNGDecodeParam(); diff --git a/src/java/org/apache/fop/image/TIFFImage.java b/src/java/org/apache/fop/image/TIFFImage.java index 7aa327c99..23337d01e 100644 --- a/src/java/org/apache/fop/image/TIFFImage.java +++ b/src/java/org/apache/fop/image/TIFFImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +21,17 @@ package org.apache.fop.image; import java.awt.color.ColorSpace; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFDirectory; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFField; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory; +import org.apache.xmlgraphics.image.codec.tiff.TIFFField; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; +import org.apache.xmlgraphics.image.rendered.CachableRed; import org.apache.commons.io.IOUtils; /** * TIFF implementation using the Batik codecs. */ -public class TIFFImage extends BatikImage { +public class TIFFImage extends XmlGraphicsCommonsImage { private int compression = 0; private int stripCount = 0; @@ -62,10 +62,13 @@ public class TIFFImage extends BatikImage { return stripCount; } - /** @see org.apache.fop.image.BatikImage */ + /** + * @see org.apache.fop.image.XmlGraphicsCommonsImage#decodeImage( + * org.apache.xmlgraphics.image.codec.util.SeekableStream) + */ protected CachableRed decodeImage(SeekableStream stream) throws IOException { - org.apache.batik.ext.awt.image.codec.tiff.TIFFImage img - = new org.apache.batik.ext.awt.image.codec.tiff.TIFFImage + org.apache.xmlgraphics.image.codec.tiff.TIFFImage img + = new org.apache.xmlgraphics.image.codec.tiff.TIFFImage (stream, null, 0); TIFFDirectory dir = (TIFFDirectory)img.getProperty("tiff_directory"); TIFFField fld = dir.getField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT); diff --git a/src/java/org/apache/fop/image/BatikImage.java b/src/java/org/apache/fop/image/XmlGraphicsCommonsImage.java similarity index 74% rename from src/java/org/apache/fop/image/BatikImage.java rename to src/java/org/apache/fop/image/XmlGraphicsCommonsImage.java index 1f6d7405b..ee079aad5 100644 --- a/src/java/org/apache/fop/image/BatikImage.java +++ b/src/java/org/apache/fop/image/XmlGraphicsCommonsImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,24 +22,25 @@ import java.awt.Color; import java.awt.Transparency; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; +import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream; -import org.apache.batik.ext.awt.image.codec.FileCacheSeekableStream; -import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.GraphicsUtil; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.codec.util.MemoryCacheSeekableStream; +import org.apache.xmlgraphics.image.codec.util.FileCacheSeekableStream; +import org.apache.xmlgraphics.image.rendered.CachableRed; + import org.apache.commons.io.IOUtils; /** - * FopImage object using TIFF - * @author Eric SCHAEFFER + * Abstract FopImage implementation which uses the internal codecs from XML Graphics Commons. * @see AbstractFopImage * @see FopImage */ -public abstract class BatikImage extends AbstractFopImage { +public abstract class XmlGraphicsCommonsImage extends AbstractFopImage { private byte[] softMask = null; @@ -57,7 +58,7 @@ public abstract class BatikImage extends AbstractFopImage { * Constructs a new BatikImage instance. * @param imgReader basic metadata for the image */ - public BatikImage(FopImage.ImageInfo imgReader) { + public XmlGraphicsCommonsImage(FopImage.ImageInfo imgReader) { super(imgReader); } @@ -105,7 +106,7 @@ public abstract class BatikImage extends AbstractFopImage { } } } else { - cr = new Any2sRGBRed(cr); + cr = GraphicsUtil.convertTosRGB(cr); } // Get our current ColorModel @@ -187,32 +188,7 @@ public abstract class BatikImage extends AbstractFopImage { this.bitmaps = new byte[this.width * this.height * 3]; - WritableRaster wr = (WritableRaster)cr.getData(); - BufferedImage bi = new BufferedImage - (cm, wr.createWritableTranslatedChild(0, 0), - cm.isAlphaPremultiplied(), null); - int [] tmpMap = new int[this.width]; - int idx = 0; - int sfIdx = 0; - for (int y = 0; y < this.height; y++) { - tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width); - if (softMask != null) { - for (int x = 0; x < this.width; x++) { - int pix = tmpMap[x]; - this.softMask[sfIdx++] = (byte)(pix >>> 24); - this.bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF); - this.bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF); - this.bitmaps[idx++] = (byte)((pix) & 0xFF); - } - } else { - for (int x = 0; x < this.width; x++) { - int pix = tmpMap[x]; - this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF); - this.bitmaps[idx++] = (byte)((pix >> 8) & 0xFF); - this.bitmaps[idx++] = (byte)((pix) & 0xFF); - } - } - } + constructBitmaps(cr, this.bitmaps, this.softMask); } catch (Exception ex) { log.error("Error while loading image (Batik): " + ex.getMessage(), ex); } finally { @@ -225,4 +201,37 @@ public abstract class BatikImage extends AbstractFopImage { } } } -}; + + private static void constructBitmaps(RenderedImage red, byte[] bitmaps, byte[] softMask) { + WritableRaster wr = (WritableRaster)red.getData(); + ColorModel cm = red.getColorModel(); + BufferedImage bi = new BufferedImage + (cm, wr.createWritableTranslatedChild(0, 0), + cm.isAlphaPremultiplied(), null); + int width = red.getWidth(); + int height = red.getHeight(); + int [] tmpMap = new int[width]; + int idx = 0; + int sfIdx = 0; + for (int y = 0; y < height; y++) { + tmpMap = bi.getRGB(0, y, width, 1, tmpMap, 0, width); + if (softMask != null) { + for (int x = 0; x < width; x++) { + int pix = tmpMap[x]; + softMask[sfIdx++] = (byte)(pix >>> 24); + bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF); + bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF); + bitmaps[idx++] = (byte)((pix) & 0xFF); + } + } else { + for (int x = 0; x < width; x++) { + int pix = tmpMap[x]; + bitmaps[idx++] = (byte)((pix >> 16) & 0xFF); + bitmaps[idx++] = (byte)((pix >> 8) & 0xFF); + bitmaps[idx++] = (byte)((pix) & 0xFF); + } + } + } + } + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/pdf/ASCII85Filter.java b/src/java/org/apache/fop/pdf/ASCII85Filter.java index 689feb4a4..debb278fb 100644 --- a/src/java/org/apache/fop/pdf/ASCII85Filter.java +++ b/src/java/org/apache/fop/pdf/ASCII85Filter.java @@ -21,7 +21,7 @@ package org.apache.fop.pdf; import java.io.OutputStream; import java.io.IOException; -import org.apache.fop.util.ASCII85OutputStream; +import org.apache.xmlgraphics.util.io.ASCII85OutputStream; /** * PDF Filter for ASCII85. diff --git a/src/java/org/apache/fop/pdf/ASCIIHexFilter.java b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java index 9da799a19..72153397d 100644 --- a/src/java/org/apache/fop/pdf/ASCIIHexFilter.java +++ b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java @@ -21,7 +21,7 @@ package org.apache.fop.pdf; import java.io.OutputStream; import java.io.IOException; -import org.apache.fop.util.ASCIIHexOutputStream; +import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream; /** * ASCII Hex filter for PDF streams. diff --git a/src/java/org/apache/fop/pdf/FlateFilter.java b/src/java/org/apache/fop/pdf/FlateFilter.java index f9bf5d61a..e9e2d4327 100644 --- a/src/java/org/apache/fop/pdf/FlateFilter.java +++ b/src/java/org/apache/fop/pdf/FlateFilter.java @@ -18,11 +18,11 @@ package org.apache.fop.pdf; -import org.apache.fop.util.FlateEncodeOutputStream; - import java.io.OutputStream; import java.io.IOException; +import org.apache.xmlgraphics.util.io.FlateEncodeOutputStream; + /** * A filter to deflate a stream. *

    diff --git a/src/java/org/apache/fop/render/RendererFactory.java b/src/java/org/apache/fop/render/RendererFactory.java index 4108043bf..f2c052317 100644 --- a/src/java/org/apache/fop/render/RendererFactory.java +++ b/src/java/org/apache/fop/render/RendererFactory.java @@ -24,19 +24,18 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -//Avalon import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.container.ContainerUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -//FOP +import org.apache.xmlgraphics.util.Service; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.AreaTreeHandler; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.util.Service; /** * Factory for FOEventHandlers and Renderers. @@ -268,12 +267,13 @@ public class RendererFactory { = Service.providers(Renderer.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + AbstractRendererMaker maker = (AbstractRendererMaker)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding maker for Renderer: " + str); + log.debug("Dynamically adding maker for Renderer: " + + maker.getClass().getName()); } - addRendererMaker(str); + addRendererMaker(maker); } catch (IllegalArgumentException e) { log.error("Error while adding maker for Renderer", e); } @@ -292,12 +292,13 @@ public class RendererFactory { = Service.providers(FOEventHandler.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + AbstractFOEventHandlerMaker maker = (AbstractFOEventHandlerMaker)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding maker for FOEventHandler: " + str); + log.debug("Dynamically adding maker for FOEventHandler: " + + maker.getClass().getName()); } - addFOEventHandlerMaker(str); + addFOEventHandlerMaker(maker); } catch (IllegalArgumentException e) { log.error("Error while adding maker for FOEventHandler", e); } diff --git a/src/java/org/apache/fop/render/XMLHandlerRegistry.java b/src/java/org/apache/fop/render/XMLHandlerRegistry.java index 1603f74ec..c972f0322 100644 --- a/src/java/org/apache/fop/render/XMLHandlerRegistry.java +++ b/src/java/org/apache/fop/render/XMLHandlerRegistry.java @@ -24,7 +24,8 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.util.Service; + +import org.apache.xmlgraphics.util.Service; /** * This class holds references to various XML handlers used by FOP. It also @@ -148,12 +149,12 @@ public class XMLHandlerRegistry { Iterator providers = Service.providers(XMLHandler.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + XMLHandler handler = (XMLHandler)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding XMLHandler: " + str); + log.debug("Dynamically adding XMLHandler: " + handler.getClass().getName()); } - addXMLHandler(str); + addXMLHandler(handler); } catch (IllegalArgumentException e) { log.error("Error while adding XMLHandler", e); } diff --git a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java index f6ed458c5..e89275484 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 The Apache Software Foundation. + * Copyright 2005-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import org.apache.batik.ext.awt.image.codec.PNGEncodeParam; -import org.apache.batik.ext.awt.image.codec.PNGImageEncoder; +import org.apache.xmlgraphics.image.writer.ImageWriter; +import org.apache.xmlgraphics.image.writer.ImageWriterParams; +import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; + import org.apache.commons.io.IOUtils; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.PageViewport; @@ -50,9 +53,6 @@ public class PNGRenderer extends Java2DRenderer { /** The output directory where images are to be written */ private File outputDir; - /** The PNGEncodeParam for the image */ - private PNGEncodeParam renderParams; - /** The OutputStream for the first Image */ private OutputStream firstOutputStream; @@ -115,17 +115,13 @@ public class PNGRenderer extends Java2DRenderer { // Encode this image log.debug("Encoding page " + (i + 1)); - renderParams = PNGEncodeParam.getDefaultEncodeParam(image); - - // Set resolution - float pixSzMM = userAgent.getTargetPixelUnitToMillimeter(); - // num Pixs in 1 Meter - int numPix = (int)((1000 / pixSzMM) + 0.5); - renderParams.setPhysicalDimension(numPix, numPix, 1); // 1 means 'pix/meter' + ImageWriterParams params = new ImageWriterParams(); + params.setResolution(Math.round(userAgent.getTargetResolution())); // Encode PNG image - PNGImageEncoder encoder = new PNGImageEncoder(os, renderParams); - encoder.encode(image); + ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType()); + log.debug("Writing image using " + writer.getClass().getName()); + writer.writeImage(image, os, params); } finally { //Only close self-created OutputStreams if (os != firstOutputStream) { diff --git a/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java b/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java index 3f7ed34ab..cfef97430 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java +++ b/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 The Apache Software Foundation. + * Copyright 2005-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import org.apache.batik.ext.awt.image.codec.PNGEncodeParam; -import org.apache.batik.ext.awt.image.codec.PNGImageEncoder; +import org.apache.xmlgraphics.image.codec.png.PNGEncodeParam; +import org.apache.xmlgraphics.image.codec.png.PNGImageEncoder; + import org.apache.commons.io.IOUtils; + import org.apache.fop.apps.FOPException; import org.apache.fop.area.PageViewport; import org.apache.fop.render.java2d.Java2DRenderer; diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java index 14e70d959..5379e6998 100644 --- a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,12 +33,12 @@ import java.util.Iterator; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.batik.ext.awt.image.GraphicsUtil; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFEncodeParam; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFField; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageEncoder; -import org.apache.batik.ext.awt.image.rendered.FormatRed; +import org.apache.xmlgraphics.image.GraphicsUtil; +import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam; +import org.apache.xmlgraphics.image.codec.tiff.TIFFField; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder; +import org.apache.xmlgraphics.image.rendered.FormatRed; import org.apache.commons.logging.Log; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; diff --git a/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java deleted file mode 100644 index 33c366a4d..000000000 --- a/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.awt.Color; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.io.OutputStream; -import java.io.IOException; - -//FOP -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontSetup; - -/** - * This class is a wrapper for the PSGraphics2D that - * is used to create a full document around the PostScript rendering from - * PSGraphics2D. - * - * @author Keiron Liddle - * @version $Id$ - * @see org.apache.fop.render.ps.PSGraphics2D - */ -public abstract class AbstractPSDocumentGraphics2D extends PSGraphics2D { - - protected static final Integer ZERO = new Integer(0); - - protected int width; - protected int height; - - protected float viewportWidth; - protected float viewportHeight; - - protected int pagecount; - protected boolean pagePending; - - protected Shape initialClip; - protected AffineTransform initialTransform; - - - /** - * Create a new AbstractPSDocumentGraphics2D. - * This is used to create a new PostScript 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. - */ - AbstractPSDocumentGraphics2D(boolean textAsShapes) { - super(textAsShapes); - - if (!textAsShapes) { - fontInfo = new FontInfo(); - FontSetup.setup(fontInfo, null, null); - } - } - - /** - * 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; - this.pagecount = 0; - this.pagePending = false; - - //Setup for PostScript generation - setPSGenerator(new PSGenerator(stream)); - - writeFileHeader(); - } - - protected abstract void writeFileHeader() throws IOException; - - /** - * Create a new AbstractPSDocumentGraphics2D. - * This is used to create a new PostScript 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 AbstractPSDocumentGraphics2D(boolean textAsShapes, OutputStream stream, - int width, int height) throws IOException { - this(textAsShapes); - setupDocument(stream, width, height); - } - - /** - * 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 PostScript document that is to be created. - * The result is scaled so that the SVG fits correctly inside the - * PostScript document. - * @param w the width of the page - * @param h the height of the page - * @throws IOException in case of an I/O problem - */ - public void setSVGDimension(float w, float h) throws IOException { - this.viewportWidth = w; - this.viewportHeight = h; - /* - if (w != this.width || h != this.height) { - gen.concatMatrix(width / w, 0, 0, height / h, 0, 0); - }*/ - } - - /** - * Set the background of the PostScript document. - * This is used to set the background for the PostScript document - * Rather than leaving it as the default white. - * @param col the background colour to fill - */ - public void setBackgroundColor(Color col) { - /**(todo) Implement this */ - /* - 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"); - */ - } - - public int getPageCount() { - return this.pagecount; - } - - public void nextPage() throws IOException { - closePage(); - } - - protected void closePage() throws IOException { - if (!this.pagePending) { - return; //ignore - } - //Finish page - writePageTrailer(); - this.pagePending = false; - } - - /** - * Writes the page header for a page. - * @throws IOException In case an I/O error occurs - */ - protected abstract void writePageHeader() throws IOException; - - /** - * Writes the page trailer for a page. - * @throws IOException In case an I/O error occurs - */ - protected abstract void writePageTrailer() throws IOException; - - - /** {@inheritDoc} */ - protected void preparePainting() { - if (this.pagePending) { - return; - } - try { - startPage(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - protected void startPage() throws IOException { - if (this.pagePending) { - throw new IllegalStateException("Close page first before starting another"); - } - //Start page - this.pagecount++; - - if (this.initialTransform == null) { - //Save initial transformation matrix - this.initialTransform = getTransform(); - this.initialClip = getClip(); - } else { - //Reset transformation matrix - setTransform(this.initialTransform); - setClip(this.initialClip); - } - - writePageHeader(); - if ((this.viewportWidth != this.width - || this.viewportHeight != this.height) - && (this.viewportWidth > 0) && (this.viewportHeight > 0)){ - gen.concatMatrix(this.width / this.viewportWidth, 0, - 0, -1 * (this.height / this.viewportHeight), - 0, this.height); - } else { - gen.concatMatrix(1, 0, 0, -1, 0, this.height); - } - gen.writeDSCComment(DSCConstants.END_PAGE_SETUP); - this.pagePending = true; - } - - /** - * 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 { - if (this.pagePending) { - closePage(); - } - - //Finish document - gen.writeDSCComment(DSCConstants.TRAILER); - gen.writeDSCComment(DSCConstants.PAGES, new Integer(this.pagecount)); - gen.writeDSCComment(DSCConstants.EOF); - gen.flush(); - } - - /** - * This constructor supports the create method - * @param g the PostScript document graphics to make a copy of - */ - public AbstractPSDocumentGraphics2D(AbstractPSDocumentGraphics2D g) { - super(g); - } - - -} - diff --git a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java index 7ce111f33..bf960185d 100644 --- a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java @@ -24,7 +24,6 @@ import java.awt.Color; import java.io.IOException; import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.container.ContainerUtil; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.UnitProcessor; import org.apache.batik.transcoder.TranscoderException; @@ -32,7 +31,11 @@ import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.ImageTranscoder; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontSetup; import org.apache.fop.svg.AbstractFOPTranscoder; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.TextHandler; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGLength; @@ -62,7 +65,6 @@ import org.w3c.dom.svg.SVGLength; * millimeter conversion factor. * * @author Keiron Liddle - * @author Jeremias Maerki * @version $Id$ */ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { @@ -92,15 +94,11 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { throws TranscoderException { graphics = createDocumentGraphics2D(); - - try { - if (this.cfg != null) { - ContainerUtil.configure(graphics, this.cfg); - } - ContainerUtil.initialize(graphics); - } catch (Exception e) { - throw new TranscoderException( - "Error while setting up PDFDocumentGraphics2D", e); + if (!isTextStroked()) { + FontInfo fontInfo = new FontInfo(); + //TODO Do custom font configuration here somewhere/somehow + FontSetup.setup(fontInfo, null, null); + graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo)); } super.transcode(document, uri, output); @@ -117,18 +115,17 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { UnitProcessor.HORIZONTAL_LENGTH, uctx); int h = (int)(heightInPt + 0.5); getLogger().trace("document size: " + w + "pt x " + h + "pt"); - try { graphics.setupDocument(output.getOutputStream(), w, h); - graphics.setSVGDimension(width, height); + graphics.setViewportDimension(width, height); 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()); + (new org.apache.xmlgraphics.java2d.GraphicContext()); graphics.setTransform(curTxf); this.root.paint(graphics); @@ -138,17 +135,29 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder { throw new TranscoderException(ex); } } - - protected BridgeContext createBridgeContext() { - /*boolean stroke = true; + + /** @return true if text should be stroked rather than painted using text operators */ + protected boolean isTextStroked() { + boolean stroke = false; if (hints.containsKey(KEY_STROKE_TEXT)) { stroke = ((Boolean)hints.get(KEY_STROKE_TEXT)).booleanValue(); - }*/ + } + return stroke; + } + + /** @see org.apache.batik.transcoder.SVGAbstractTranscoder#createBridgeContext() */ + protected BridgeContext createBridgeContext() { BridgeContext ctx = new BridgeContext(userAgent); - PSTextPainter textPainter = new PSTextPainter(graphics.getFontInfo()); - ctx.setTextPainter(textPainter); - ctx.putBridge(new PSTextElementBridge(textPainter)); + if (!isTextStroked()) { + TextHandler handler = graphics.getCustomTextHandler(); + if (handler instanceof NativeTextHandler) { + NativeTextHandler nativeTextHandler = (NativeTextHandler)handler; + PSTextPainter textPainter = new PSTextPainter(nativeTextHandler); + ctx.setTextPainter(textPainter); + ctx.putBridge(new PSTextElementBridge(textPainter)); + } + } //ctx.putBridge(new PSImageElementBridge()); return ctx; diff --git a/src/java/org/apache/fop/render/ps/DSCConstants.java b/src/java/org/apache/fop/render/ps/DSCConstants.java deleted file mode 100644 index f87b744db..000000000 --- a/src/java/org/apache/fop/render/ps/DSCConstants.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -/** - * This class defines constants with Strings for the DSC specification. - * - * @author Apache FOP Development Team - * @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"; - - /** Lead-in for an EPS file */ - public static final String EPSF_30 = "EPSF-3.0"; - - /** Bounding box for the document */ - public static final String BBOX = "BoundingBox"; - /** High-resolution bounding box for the document */ - public static final String HIRES_BBOX = "HiResBoundingBox"; - /** 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"; - /** High-resolution bounding box for a page */ - public static final String PAGE_HIRES_BBOX = "PageHiResBoundingBox"; - /** 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 */ - /** - * This comment indicates all types of paper media (paper sizes, weight, color) - * this document requires. - */ - public static final String DOCUMENT_MEDIA = "DocumentMedia"; - /** This comment provides a list of resources the document needs */ - public static final String DOCUMENT_NEEDED_RESOURCES = "DocumentNeededResources"; - /** This comment provides a list of resources the document includes */ - public static final String DOCUMENT_SUPPLIED_RESOURCES = "DocumentSuppliedResources"; - //Skipping %%DocumentPrinterRequired - //Skipping %%DocumentNeededFiles -> deprecated - //Skipping %%DocumentSuppliedFiles -> deprecated - //Skipping %%DocumentFonts -> deprecated - //Skipping %%DocumentNeededFonts -> deprecated - //Skipping %%DocumentSuppliedFonts -> deprecated - //Skipping %%DocumentNeededProcSets -> deprecated - //Skipping %%DocumentSuppliedProcSets -> deprecated - //Skipping %%OperatorIntervention - //Skipping %%OperatorMessage - //Skipping %%ProofMode - /** - * This comment describes document requirements, such as duplex printing, - * hole punching, collating, or other physical document processing needs. - */ - public static final String REQUIREMENTS = "Requirements"; - //Skipping %%VMlocation - //Skipping %%VMusage - - // ----==== 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"; - - // ----==== Requirement Page Comments ====---- - - //Skipping %%PageFonts -> deprecated - //Skipping %%PageFiles -> deprecated - /** Indicates that the paper attributes denoted by medianame are invoked on this page. */ - public static final String PAGE_MEDIA = "PageMedia"; - /** - * This is the page-level invocation of a combination of the options listed in - * the %%Requirements: comment. - */ - public static final String PAGE_REQUIREMENTS = "PageRequirements"; - /** - * This comment indicates the names and values of all resources that are needed - * or supplied on the present page. - */ - public static final String PAGE_RESOURCES = "PageResources"; - -} diff --git a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java deleted file mode 100644 index 461cfcadd..000000000 --- a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2003-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.io.IOException; - -import org.apache.fop.Version; - -/** - * This class is a wrapper for the AbstractPSDocumentGraphics2D that - * is used to create EPS (Encapsulated PostScript) files instead of PS file. - * - * @version $Id$ - * @see org.apache.fop.render.ps.PSGraphics2D - * @see org.apache.fop.render.ps.AbstractPSDocumentGraphics2D - */ -public class EPSDocumentGraphics2D extends AbstractPSDocumentGraphics2D { - - /** - * Create a new EPSDocumentGraphics2D. - * This is used to create a new EPS 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. - */ - public EPSDocumentGraphics2D(boolean textAsShapes) { - super(textAsShapes); - } - - protected void writeFileHeader() throws IOException { - final Long pagewidth = new Long(this.width); - final Long pageheight = new Long(this.height); - - //PostScript Header - gen.writeln(DSCConstants.PS_ADOBE_30 + " " + DSCConstants.EPSF_30); - gen.writeDSCComment(DSCConstants.CREATOR, - new String[] {"Apache FOP " + Version.getVersion() - + ": EPS Transcoder for SVG"}); - gen.writeDSCComment(DSCConstants.CREATION_DATE, - new Object[] {new java.util.Date()}); - gen.writeDSCComment(DSCConstants.PAGES, new Integer(0)); - gen.writeDSCComment(DSCConstants.BBOX, new Object[] - {ZERO, ZERO, pagewidth, pageheight}); - gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new Integer(gen.getPSLevel())); - gen.writeDSCComment(DSCConstants.END_COMMENTS); - - //Prolog - gen.writeDSCComment(DSCConstants.BEGIN_PROLOG); - PSProcSets.writeFOPStdProcSet(gen); - PSProcSets.writeFOPEPSProcSet(gen); - if (fontInfo != null) { - PSFontUtils.writeFontDict(gen, fontInfo); - } - gen.writeDSCComment(DSCConstants.END_PROLOG); - } - - protected void writePageHeader() throws IOException { - Integer pageNumber = new Integer(this.pagecount); - gen.writeDSCComment(DSCConstants.PAGE, new Object[] - {pageNumber.toString(), pageNumber}); - gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] - {ZERO, ZERO, new Integer(width), new Integer(height)}); - gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); - if (fontInfo != null) { - gen.writeln("FOPFonts begin"); - } - } - - protected void writePageTrailer() throws IOException { - gen.writeDSCComment(DSCConstants.PAGE_TRAILER); - gen.writeDSCComment(DSCConstants.END_PAGE); - } - -} diff --git a/src/java/org/apache/fop/render/ps/EPSTranscoder.java b/src/java/org/apache/fop/render/ps/EPSTranscoder.java index 37f4c8c78..8ca7c9b5b 100644 --- a/src/java/org/apache/fop/render/ps/EPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/EPSTranscoder.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2004,2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ package org.apache.fop.render.ps; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D; + /** * This class enables to transcode an input to a EPS document. * @@ -43,7 +46,6 @@ package org.apache.fop.render.ps; * millimeter conversion factor. * * @author Keiron Liddle - * @author Jeremias Maerki * @version $Id$ */ public class EPSTranscoder extends AbstractPSTranscoder { @@ -55,6 +57,7 @@ public class EPSTranscoder extends AbstractPSTranscoder { super(); } + /** @see AbstractPSTranscoder#createDocumentGraphics2D() */ protected AbstractPSDocumentGraphics2D createDocumentGraphics2D() { return new EPSDocumentGraphics2D(false); } diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java new file mode 100644 index 000000000..2578b4c78 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java @@ -0,0 +1,190 @@ +/* + * Copyright 1999-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.ps; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.io.IOException; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontSetup; +import org.apache.fop.fonts.FontTriplet; + +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.java2d.ps.TextHandler; +import org.apache.xmlgraphics.ps.PSGenerator; + +/** + * Specialized TextHandler implementation that the PSGraphics2D class delegates to to paint text + * using PostScript text operations. + */ +public class NativeTextHandler implements TextHandler { + + private PSGraphics2D g2d; + + /** FontInfo containing all available fonts */ + protected FontInfo fontInfo; + + /** Currently valid Font */ + protected Font font; + + /** Overriding FontState */ + protected Font overrideFont = null; + + /** the current (internal) font name */ + protected String currentFontName; + + /** the current font size in millipoints */ + protected int currentFontSize; + + /** + * Main constructor. + * @param g2d the PSGraphics2D instance this instances is used by + * @param fontInfo the FontInfo object with all available fonts + */ + public NativeTextHandler(PSGraphics2D g2d, FontInfo fontInfo) { + this.g2d = g2d; + if (fontInfo != null) { + this.fontInfo = fontInfo; + } else { + setupFontInfo(); + } + } + + private void setupFontInfo() { + //Sets up a FontInfo with default fonts + fontInfo = new FontInfo(); + FontSetup.setup(fontInfo, null, null); + } + + /** + * Return the font information associated with this object + * @return the FontInfo object + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + private PSGenerator getPSGenerator() { + return this.g2d.getPSGenerator(); + } + + /** @see org.apache.xmlgraphics.java2d.ps.TextHandler#writeSetup() */ + public void writeSetup() throws IOException { + if (fontInfo != null) { + PSFontUtils.writeFontDict(getPSGenerator(), fontInfo); + } + } + + /** @see org.apache.xmlgraphics.java2d.ps.TextHandler#writePageSetup() */ + public void writePageSetup() throws IOException { + if (fontInfo != null) { + getPSGenerator().writeln("FOPFonts begin"); + } + } + + /** + * Draw a string to the PostScript document. The text is painted using + * text operations. + * @see org.apache.xmlgraphics.java2d.ps.TextHandler#drawString(java.lang.String, float, float) + */ + public void drawString(String s, float x, float y) throws IOException { + g2d.preparePainting(); + if (this.overrideFont == null) { + java.awt.Font awtFont = g2d.getFont(); + this.font = createFont(awtFont); + } else { + this.font = this.overrideFont; + this.overrideFont = null; + } + + //Color and Font state + g2d.establishColor(g2d.getColor()); + establishCurrentFont(); + + PSGenerator gen = getPSGenerator(); + gen.saveGraphicsState(); + + //Clip + Shape imclip = g2d.getClip(); + g2d.writeClip(imclip); + + //Prepare correct transformation + AffineTransform trans = g2d.getTransform(); + gen.concatMatrix(trans); + gen.writeln(gen.formatDouble(x) + " " + + gen.formatDouble(y) + " moveto "); + gen.writeln("1 -1 scale"); + + StringBuffer sb = new StringBuffer("("); + escapeText(s, sb); + sb.append(") t "); + + gen.writeln(sb.toString()); + + gen.restoreGraphicsState(); + } + + private void escapeText(final String text, StringBuffer target) { + final int l = text.length(); + for (int i = 0; i < l; i++) { + final char ch = text.charAt(i); + final char mch = this.font.mapChar(ch); + PSGenerator.escapeChar(mch, target); + } + } + + private Font createFont(java.awt.Font f) { + String fontFamily = f.getFamily(); + if (fontFamily.equals("sanserif")) { + fontFamily = "sans-serif"; + } + int fontSize = 1000 * f.getSize(); + String style = f.isItalic() ? "italic" : "normal"; + int weight = f.isBold() ? Font.BOLD : Font.NORMAL; + + FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight); + if (triplet == null) { + triplet = fontInfo.findAdjustWeight("sans-serif", style, weight); + } + return fontInfo.getFontInstance(triplet, fontSize); + } + + private void establishCurrentFont() throws IOException { + if ((currentFontName != this.font.getFontName()) + || (currentFontSize != this.font.getFontSize())) { + PSGenerator gen = getPSGenerator(); + gen.writeln(this.font.getFontName() + " " + + gen.formatDouble(font.getFontSize() / 1000f) + " F"); + currentFontName = this.font.getFontName(); + currentFontSize = this.font.getFontSize(); + } + } + + /** + * Sets the overriding font. + * @param override Overriding Font to set + */ + public void setOverrideFont(Font override) { + this.overrideFont = override; + } + + +} diff --git a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java deleted file mode 100644 index b2a1c07a0..000000000 --- a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.awt.Graphics; -import java.io.OutputStream; -import java.io.IOException; - -//FOP -import org.apache.fop.Version; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontSetup; - -/** - * This class is a wrapper for the PSGraphics2D that - * is used to create a full document around the PostScript rendering from - * PSGraphics2D. - * - * @author Keiron Liddle - * @version $Id$ - * @see org.apache.fop.render.ps.PSGraphics2D - */ -public class PSDocumentGraphics2D extends AbstractPSDocumentGraphics2D { - - - /** - * Create a new AbstractPSDocumentGraphics2D. - * This is used to create a new PostScript 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. - */ - PSDocumentGraphics2D(boolean textAsShapes) { - super(textAsShapes); - } - - /** - * Create a new AbstractPSDocumentGraphics2D. - * This is used to create a new PostScript 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 PSDocumentGraphics2D(boolean textAsShapes, OutputStream stream, - int width, int height) throws IOException { - this(textAsShapes); - setupDocument(stream, width, height); - } - - public void nextPage() throws IOException { - closePage(); - } - - protected void writeFileHeader() throws IOException { - final Long pagewidth = new Long(this.width); - final Long pageheight = new Long(this.height); - - //PostScript Header - gen.writeln(DSCConstants.PS_ADOBE_30); - gen.writeDSCComment(DSCConstants.CREATOR, - new String[] {"Apache FOP " + Version.getVersion() - + ": PostScript Transcoder for SVG"}); - gen.writeDSCComment(DSCConstants.CREATION_DATE, - new Object[] {new java.util.Date()}); - gen.writeDSCComment(DSCConstants.PAGES, PSGenerator.ATEND); - gen.writeDSCComment(DSCConstants.BBOX, new Object[] - {ZERO, ZERO, pagewidth, pageheight}); - 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); - if (fontInfo != null) { - PSFontUtils.writeFontDict(gen, fontInfo); - } - gen.writeDSCComment(DSCConstants.END_SETUP); - } - - protected void writePageHeader() throws IOException { - Integer pageNumber = new Integer(this.pagecount); - gen.writeDSCComment(DSCConstants.PAGE, new Object[] - {pageNumber.toString(), pageNumber}); - gen.writeDSCComment(DSCConstants.PAGE_BBOX, new Object[] - {ZERO, ZERO, new Integer(width), new Integer(height)}); - gen.writeDSCComment(DSCConstants.BEGIN_PAGE_SETUP); - gen.writeln("<<"); - gen.writeln("/PageSize [" + width + " " + height + "]"); - gen.writeln("/ImagingBBox null"); - gen.writeln(">> setpagedevice"); - if (fontInfo != null) { - gen.writeln("FOPFonts begin"); - } - } - - protected void writePageTrailer() throws IOException { - gen.writeln("showpage"); - gen.writeDSCComment(DSCConstants.PAGE_TRAILER); - gen.writeDSCComment(DSCConstants.END_PAGE); - } - - /** - * This constructor supports the create method - * @param g the PostScript document graphics to make a copy of - */ - public PSDocumentGraphics2D(PSDocumentGraphics2D 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 PSDocumentGraphics2D(this); - } - -} - diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java index 3478a0751..f56e18bb9 100644 --- a/src/java/org/apache/fop/render/ps/PSFontUtils.java +++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java @@ -18,7 +18,6 @@ package org.apache.fop.render.ps; -import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -29,22 +28,20 @@ import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.io.EndianUtils; -import org.apache.commons.io.IOUtils; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontType; -import org.apache.fop.fonts.Glyphs; import org.apache.fop.fonts.LazyFont; import org.apache.fop.fonts.Typeface; -import org.apache.fop.util.ASCIIHexOutputStream; -import org.apache.fop.util.SubInputStream; +import org.apache.xmlgraphics.ps.DSCConstants; +import org.apache.xmlgraphics.ps.PSGenerator; +import org.apache.xmlgraphics.ps.PSResource; /** * Utility code for font handling in PostScript. */ -public class PSFontUtils { +public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { /** * Generates the PostScript code for the font dictionary. @@ -133,56 +130,6 @@ public class PSFontUtils { return fontResources; } - /** - * This method reads a Type 1 font from a stream and embeds it into a PostScript stream. - * Note: Only the IBM PC Format as described in section 3.3 of the Adobe Technical Note #5040 - * is supported. - * @param gen The PostScript generator - * @param in the InputStream from which to read the Type 1 font - * @throws IOException in case an I/O problem occurs - */ - private static void embedType1Font(PSGenerator gen, InputStream in) throws IOException { - boolean finished = false; - while (!finished) { - int segIndicator = in.read(); - if (segIndicator < 0) { - throw new IOException("Unexpected end-of-file while reading segment indicator"); - } else if (segIndicator != 128) { - throw new IOException("Expected ASCII 128, found: " + segIndicator); - } - int segType = in.read(); - if (segType < 0) { - throw new IOException("Unexpected end-of-file while reading segment type"); - } - int dataSegLen = 0; - switch (segType) { - case 1: //ASCII - dataSegLen = EndianUtils.readSwappedInteger(in); - - BufferedReader reader = new BufferedReader( - new java.io.InputStreamReader( - new SubInputStream(in, dataSegLen), "US-ASCII")); - String line; - while ((line = reader.readLine()) != null) { - gen.writeln(line); - } - break; - case 2: //binary - dataSegLen = EndianUtils.readSwappedInteger(in); - - SubInputStream sin = new SubInputStream(in, dataSegLen); - ASCIIHexOutputStream hexOut = new ASCIIHexOutputStream(gen.getOutputStream()); - IOUtils.copy(sin, hexOut); - gen.newLine(); - break; - case 3: //EOF - finished = true; - break; - default: throw new IOException("Unsupported segment type: " + segType); - } - } - } - private static InputStream getInputStreamOnFont(PSGenerator gen, CustomFont font) throws IOException { if (font.isEmbeddable()) { @@ -220,28 +167,4 @@ public class PSFontUtils { } } - private static void defineWinAnsiEncoding(PSGenerator gen) throws IOException { - gen.writeln("/WinAnsiEncoding ["); - for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { - if (i > 0) { - if ((i % 5) == 0) { - gen.newLine(); - } else { - gen.write(" "); - } - } - final char ch = Glyphs.WINANSI_ENCODING[i]; - final String glyphname = Glyphs.charToGlyphName(ch); - if ("".equals(glyphname)) { - gen.write("/" + Glyphs.NOTDEF); - } else { - gen.write("/"); - gen.write(glyphname); - } - } - gen.newLine(); - gen.writeln("] def"); - } - - } diff --git a/src/java/org/apache/fop/render/ps/PSGenerator.java b/src/java/org/apache/fop/render/ps/PSGenerator.java deleted file mode 100644 index 14d5b18fa..000000000 --- a/src/java/org/apache/fop/render/ps/PSGenerator.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.io.OutputStream; -import java.io.IOException; -import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Date; -import java.util.Iterator; -import java.util.Locale; -import java.util.Set; -import java.util.Stack; - -import javax.xml.transform.Source; - -/** - * This class is used to output PostScript code to an OutputStream. - * - * @author Apache FOP Development Team - * @version $Id$ - */ -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() { - }; - - /** Line feed used by PostScript */ - public static final char LF = '\n'; - - private OutputStream out; - private boolean commentsEnabled = true; - - private Stack graphicsStateStack = new Stack(); - private PSState currentState; - //private DecimalFormat df3 = new DecimalFormat("0.000", new DecimalFormatSymbols(Locale.US)); - private DecimalFormat df3 = new DecimalFormat("0.###", new DecimalFormatSymbols(Locale.US)); - private DecimalFormat df5 = new DecimalFormat("0.#####", new DecimalFormatSymbols(Locale.US)); - - 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); - } - - /** - * Returns the OutputStream the PSGenerator writes to. - * @return the OutputStream - */ - public OutputStream getOutputStream() { - return this.out; - } - - /** - * Returns the selected PostScript level. - * (Hardcoded to level 2 for the moment.) - * @return the PostScript level - */ - public int getPSLevel() { - return 2; - } - - /** - * Attempts to resolve the given URI. PSGenerator should be subclasses to provide more - * sophisticated URI resolution. - * @param uri URI to access - * @return A {@link javax.xml.transform.Source} object, or null if the URI - * cannot be resolved. - */ - public Source resolveURI(String uri) { - return new javax.xml.transform.stream.StreamSource(uri); - } - - /** - * Writes a newline character to the OutputStream. - * - * @throws IOException In case of an I/O problem - */ - public final void newLine() throws IOException { - out.write(LF); - } - - /** - * Formats a double value for PostScript output. - * - * @param value value to format - * @return the formatted value - */ - public String formatDouble(double value) { - return df3.format(value); - } - - /** - * Formats a double value for PostScript output (higher resolution). - * - * @param value value to format - * @return the formatted value - */ - public String formatDouble5(double value) { - return df5.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 { - /* @todo Check disabled until clarification. - 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 a comment to the stream and ends the line. Output of comments can - * be disabled to reduce the size of the generated file. - * - * @param comment comment to write - * @exception IOException In case of an I/O problem - */ - public void commentln(String comment) throws IOException { - if (this.commentsEnabled) { - writeln(comment); - } - } - - /** - * 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 Double) { - tempBuffer.append(df3.format(params[i])); - } else if (params[i] instanceof Number) { - tempBuffer.append(params[i].toString()); - } else if (params[i] instanceof Date) { - DateFormat datef = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - tempBuffer.append(convertStringToDSC(datef.format((Date)params[i]))); - } else if (params[i] instanceof PSResource) { - tempBuffer.append(((PSResource)params[i]).getResourceSpecification()); - } 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 = new PSState(this.currentState, false); - this.graphicsStateStack.push(this.currentState); - this.currentState = state; - } - - /** - * Restores the last graphics state of the rendering engine. - * @return true if the state was restored, false if there's a stack underflow. - * @exception IOException In case of an I/O problem - */ - public boolean restoreGraphicsState() throws IOException { - if (this.graphicsStateStack.size() > 0) { - writeln("grestore"); - this.currentState = (PSState)this.graphicsStateStack.pop(); - return true; - } else { - return false; - } - } - - - /** - * Returns the current graphics state. - * @return the current graphics state - */ - public PSState getCurrentState() { - return this.currentState; - } - - /** - * 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 { - AffineTransform at = new AffineTransform(a, b, c, d, e, f); - concatMatrix(at); - - } - - /** - * 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]); - } - - /** - * Concats the transformations matric. - * @param at the AffineTransform whose matrix to use - * @exception IOException In case of an I/O problem - */ - public void concatMatrix(AffineTransform at) throws IOException { - double[] matrix = new double[6]; - at.getMatrix(matrix); - getCurrentState().concatMatrix(at); - writeln("[" + formatDouble5(matrix[0]) + " " - + formatDouble5(matrix[1]) + " " - + formatDouble5(matrix[2]) + " " - + formatDouble5(matrix[3]) + " " - + formatDouble5(matrix[4]) + " " - + formatDouble5(matrix[5]) + "] concat"); - } - - /** - * Adds a rectangle to the current path. - * @param x upper left corner - * @param y upper left corner - * @param w width - * @param h height - * @exception IOException In case of an I/O problem - */ - public void defineRect(double x, double y, double w, double h) - throws IOException { - writeln(formatDouble(x) - + " " + formatDouble(y) - + " " + formatDouble(w) - + " " + formatDouble(h) - + " re"); - } - - /** - * Establishes the specified line cap style. - * @param linecap the line cap style (0, 1 or 2) as defined by the setlinecap command. - * @exception IOException In case of an I/O problem - */ - public void useLineCap(int linecap) throws IOException { - if (getCurrentState().useLineCap(linecap)) { - writeln(linecap + " setlinecap"); - } - } - - /** - * Establishes the specified line width. - * @param width the line width as defined by the setlinewidth command. - * @exception IOException In case of an I/O problem - */ - public void useLineWidth(double width) throws IOException { - if (getCurrentState().useLineWidth(width)) { - writeln(formatDouble(width) + " setlinewidth"); - } - } - - /** - * Establishes the specified dash pattern. - * @param pattern the dash pattern as defined by the setdash command. - * @exception IOException In case of an I/O problem - */ - public void useDash(String pattern) throws IOException { - if (pattern == null) { - pattern = PSState.DEFAULT_DASH; - } - if (getCurrentState().useDash(pattern)) { - writeln(pattern + " setdash"); - } - } - - /** - * Establishes the specified color (RGB). - * @param col the color as defined by the setrgbcolor command. - * @exception IOException In case of an I/O problem - */ - public void useRGBColor(Color col) throws IOException { - if (col == null) { - col = PSState.DEFAULT_RGB_COLOR; - } - if (getCurrentState().useColor(col)) { - float[] comps = col.getColorComponents(null); - writeln(formatDouble(comps[0]) - + " " + formatDouble(comps[1]) - + " " + formatDouble(comps[2]) - + " setrgbcolor"); - } - } - - /** - * Establishes the specified font and size. - * @param name name of the font for the "F" command (see FOP Std Proc Set) - * @param size size of the font - * @exception IOException In case of an I/O problem - */ - public void useFont(String name, float size) throws IOException { - if (getCurrentState().useFont(name, size)) { - writeln(name + " " + formatDouble(size) + " F"); - } - } - - private Set documentSuppliedResources; - private Set documentNeededResources; - private Set pageResources; - - /** - * Notifies the generator that a new page has been started and that the page resource - * set can be cleared. - */ - public void notifyStartNewPage() { - if (pageResources != null) { - pageResources.clear(); - } - } - - /** - * Notifies the generator about the usage of a resource on the current page. - * @param res the resource being used - * @param needed true if this is a needed resource, false for a supplied resource - */ - public void notifyResourceUsage(PSResource res, boolean needed) { - if (pageResources == null) { - pageResources = new java.util.HashSet(); - } - pageResources.add(res); - if (needed) { - if (documentNeededResources == null) { - documentNeededResources = new java.util.HashSet(); - } - documentNeededResources.add(res); - } else { - if (documentSuppliedResources == null) { - documentSuppliedResources = new java.util.HashSet(); - } - documentSuppliedResources.add(res); - } - } - - /** - * Indicates whether a particular resource is supplied, rather than needed. - * @param res the resource - * @return true if the resource is registered as being supplied. - */ - public boolean isResourceSupplied(PSResource res) { - return documentSuppliedResources.contains(res); - } - - /** - * Writes a DSC comment for the accumulated used resources, either at page level or - * at document level. - * @param pageLevel true if the DSC comment for the page level should be generated, - * false for the document level (in the trailer) - * @exception IOException In case of an I/O problem - */ - public void writeResources(boolean pageLevel) throws IOException { - if (pageLevel) { - writeResourceComment(DSCConstants.PAGE_RESOURCES, pageResources); - } else { - writeResourceComment(DSCConstants.DOCUMENT_NEEDED_RESOURCES, - documentNeededResources); - writeResourceComment(DSCConstants.DOCUMENT_SUPPLIED_RESOURCES, - documentSuppliedResources); - } - } - - private void writeResourceComment(String name, Set resources) throws IOException { - if (resources == null || resources.size() == 0) { - return; - } - tempBuffer.setLength(0); - tempBuffer.append("%%"); - tempBuffer.append(name); - tempBuffer.append(" "); - boolean first = true; - Iterator i = resources.iterator(); - while (i.hasNext()) { - if (!first) { - writeln(tempBuffer.toString()); - tempBuffer.setLength(0); - tempBuffer.append("%%+ "); - } - PSResource res = (PSResource)i.next(); - tempBuffer.append(res.getResourceSpecification()); - first = false; - } - writeln(tempBuffer.toString()); - } - - /** 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 deleted file mode 100644 index eb7b59e39..000000000 --- a/src/java/org/apache/fop/render/ps/PSGraphics2D.java +++ /dev/null @@ -1,1181 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.text.AttributedCharacterIterator; -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -/* java.awt.Font is not imported to avoid confusion with - org.apache.fop.fonts.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.color.ColorSpace; -import java.awt.color.ICC_Profile; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -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; - -//Batik -import org.apache.batik.ext.awt.RenderingHintsKeyExt; -import org.apache.batik.ext.awt.g2d.AbstractGraphics2D; -import org.apache.batik.ext.awt.g2d.GraphicContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -//FOP -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.image.FopImage; - -/** - * 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$ - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D - */ -public class PSGraphics2D extends AbstractGraphics2D { - - private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); - - /** the logger for this class */ - protected Log log = LogFactory.getLog(PSTextPainter.class); - - /** the PostScript generator being created */ - protected PSGenerator gen; - - private boolean clippingDisabled = false; - - /** Currently valid FontState */ - protected Font font; - - /** Overriding FontState */ - protected Font overrideFont = null; - - /** the current (internal) font name */ - protected String currentFontName; - - /** the current font size in millipoints */ - protected int currentFontSize; - - /** - * 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 - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) - */ - public PSGraphics2D(boolean textAsShapes) { - super(textAsShapes); - } - - /** - * 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) { - this(textAsShapes); - setPSGenerator(gen); - } - - /** - * Constructor for creating copies - * @param g parent PostScript Graphics2D - */ - public PSGraphics2D(PSGraphics2D g) { - super(g); - - setPSGenerator(g.gen); - this.clippingDisabled = g.clippingDisabled; - this.font = g.font; - this.overrideFont = g.overrideFont; - this.currentFontName = g.currentFontName; - this.currentFontSize = g.currentFontSize; - this.currentColour = g.currentColour; - this.fontInfo = g.fontInfo; - } - - /** - * Sets the PostScript generator - * @param gen the PostScript generator - */ - public void setPSGenerator(PSGenerator gen) { - this.gen = gen; - } - - /** - * Sets the GraphicContext - * @param c GraphicContext to use - */ - public void setGraphicContext(GraphicContext c) { - gc = c; - setPrivateHints(); - } - - private void setPrivateHints() { - setRenderingHint(RenderingHintsKeyExt.KEY_AVOID_TILE_PAINTING, - RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_ON); - } - - /** - * 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); - } - - /** - * Return the font information associated with this object - * @return the FontInfo object - */ - public FontInfo getFontInfo() { - return fontInfo; - } - - /** - * Central handler for IOExceptions for this class. - * @param ioe IOException to handle - */ - protected void handleIOException(IOException ioe) { - //TODO Surely, there's a better way to do this. - ioe.printStackTrace(); - } - - /** - * This method is used by AbstractPSDocumentGraphics2D to prepare a new page if - * necessary. - */ - protected void preparePainting() { - //nop, used by AbstractPSDocumentGraphics2D - } - - /** - * 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) { - preparePainting(); - log.debug("drawImage: " + x + ", " + y + " " + img.getClass().getName()); - - 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, null); - AffineTransform at = getTransform(); - gen.saveGraphicsState(); - gen.concatMatrix(at); - Shape imclip = getClip(); - writeClip(imclip); - PSImageUtils.renderBitmapImage(fopimg, - x, y, width, height, gen); - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - - 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 { - private int height; - private int width; - private int bitsPerPixel; - private ColorSpace colorSpace; - private byte[] bitmaps; - private byte[] mask; - private Color transparentColor; - - TempImage(int width, int height, byte[] bitmaps, - byte[] mask) { - this.height = height; - this.width = width; - this.bitsPerPixel = 8; - this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); - this.bitmaps = bitmaps; - this.mask = mask; - } - - public String getMimeType() { - return "application/octet-stream"; - } - - public String getOriginalURI() { - return "temp-image:" + this.toString(); - } - - /** - * @see org.apache.fop.image.FopImage#load(int, org.apache.commons.logging.Log) - */ - public boolean load(int type) { - switch (type) { - case FopImage.DIMENSIONS: break; - case FopImage.BITMAP: break; - case FopImage.ORIGINAL_DATA: break; - default: throw new RuntimeException("Unknown load type: " + type); - } - return true; - } - - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } - - public ColorSpace getColorSpace() { - return this.colorSpace; - } - - public ICC_Profile getICCProfile() { - return null; - } - - public int getBitsPerPixel() { - return this.bitsPerPixel; - } - - // For transparent images - public boolean isTransparent() { - return getTransparentColor() != null; - } - - public Color getTransparentColor() { - return this.transparentColor; - } - - public boolean hasSoftMask() { - return this.mask != null; - } - - public byte[] getSoftMask() { - return this.mask; - } - - public boolean isInverted() { - return false; - } - - public byte[] getBitmaps() { - return this.bitmaps; - } - - // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() { - return getWidth() * getHeight() * 3; //Assumes RGB! - } - - // 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; - } - - /** @see org.apache.fop.image.FopImage#getIntrinsicWidth() */ - public int getIntrinsicWidth() { - return (int)(getWidth() * 72 / getHorizontalResolution()); - } - - /** @see org.apache.fop.image.FopImage#getIntrinsicHeight() */ - public int getIntrinsicHeight() { - return (int)(getHeight() * 72 / getVerticalResolution()); - } - - /** @see org.apache.fop.image.FopImage#getHorizontalResolution() */ - public double getHorizontalResolution() { - return 72; - } - - /** @see org.apache.fop.image.FopImage#getVerticalResolution() */ - public double getVerticalResolution() { - return 72; - } - - } - - - /** - * 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) { - preparePainting(); - log.warn("NYI: 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() { - this.gen = null; - this.font = null; - this.currentColour = null; - this.fontInfo = null; - } - - /** - * Processes a path iterator generating the nexessary painting operations. - * @param iter PathIterator to process - * @throws IOException In case of an I/O problem. - */ - public void processPathIterator(PathIterator iter) throws IOException { - double[] vals = new double[6]; - while (!iter.isDone()) { - int type = iter.currentSegment(vals); - switch (type) { - case PathIterator.SEG_CUBICTO: - 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]) - + " curveto"); - break; - case PathIterator.SEG_LINETO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) - + " lineto"); - break; - case PathIterator.SEG_MOVETO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) - + " M"); - break; - case PathIterator.SEG_QUADTO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) + " " - + gen.formatDouble(vals[2]) + " " - + gen.formatDouble(vals[3]) + " QUADTO "); - break; - case PathIterator.SEG_CLOSE: - gen.writeln("closepath"); - break; - default: - break; - } - iter.next(); - } - } - - /** - * 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) { - preparePainting(); - try { - gen.saveGraphicsState(); - - AffineTransform trans = getTransform(); - boolean newTransform = gen.getCurrentState().checkTransform(trans) - && !trans.isIdentity(); - - if (newTransform) { - gen.concatMatrix(trans); - } - Shape imclip = getClip(); - writeClip(imclip); - establishColor(getColor()); - - applyPaint(getPaint(), false); - applyStroke(getStroke()); - - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - 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) { - if (s == null) { - return; - } - if (!this.clippingDisabled) { - preparePainting(); - try { - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - // clip area - gen.writeln("clip"); - } 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) { - preparePainting(); - if (paint instanceof GradientPaint) { - log.warn("NYI: Gradient paint"); - } else if (paint instanceof TexturePaint) { - log.warn("NYI: texture paint"); - } - } - - /** - * Applies a new Stroke object. - * @param stroke Stroke object to use - */ - protected void applyStroke(Stroke stroke) { - preparePainting(); - try { - if (stroke instanceof BasicStroke) { - BasicStroke bs = (BasicStroke)stroke; - - float[] da = bs.getDashArray(); - if (da != null) { - gen.write("["); - for (int count = 0; count < da.length; count++) { - gen.write("" + ((int)da[count])); - if (count < da.length - 1) { - gen.write(" "); - } - } - gen.write("] "); - float offset = bs.getDashPhase(); - gen.writeln(((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; - default: log.warn("Unsupported line cap: " + ec); - } - - 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; - default: log.warn("Unsupported line join: " + lj); - } - float lw = bs.getLineWidth(); - gen.writeln(gen.formatDouble(lw) + " setlinewidth"); - - float ml = bs.getMiterLimit(); - gen.writeln(gen.formatDouble(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) { - preparePainting(); - log.warn("NYI: 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) { - preparePainting(); - log.warn("NYI: drawRenderableImage"); - } - - /** - * Establishes the given color in the PostScript interpreter. - * @param c the color to set - * @throws IOException In case of an I/O problem - */ - protected void establishColor(Color c) throws IOException { - StringBuffer p = new StringBuffer(); - float[] comps = c.getColorComponents(null); - - if (c.getColorSpace().getType() == ColorSpace.TYPE_RGB) { - // according to pdfspec 12.1 p.399 - // if the colors are the same then just use the g or G operator - boolean same = (comps[0] == comps[1] - && comps[0] == comps[2]); - // output RGB - if (same) { - p.append(gen.formatDouble(comps[0])); - } else { - for (int i = 0; i < c.getColorSpace().getNumComponents(); i++) { - if (i > 0) { - p.append(" "); - } - p.append(gen.formatDouble(comps[i])); - } - } - if (same) { - p.append(" setgray"); - } else { - p.append(" setrgbcolor"); - } - } else if (c.getColorSpace().getType() == ColorSpace.TYPE_CMYK) { - // colorspace is CMYK - for (int i = 0; i < c.getColorSpace().getNumComponents(); i++) { - if (i > 0) { - p.append(" "); - } - p.append(gen.formatDouble(comps[i])); - } - p.append(" setcmykcolor"); - } else { - // means we're in DeviceGray or Unknown. - // assume we're in DeviceGray, because otherwise we're screwed. - p.append(gen.formatDouble(comps[0])); - p.append(" setgray"); - } - gen.writeln(p.toString()); - } - - /** - * 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) { - if (this.textAsShapes) { - drawStringAsShapes(s, x, y); - } else { - drawStringAsText(s, x, y); - } - } - - /** - * Draw a string to the PostScript document. The text is painted as shapes. - * @param s the string to draw - * @param x the x position - * @param y the y position - */ - public void drawStringAsShapes(String s, float x, float y) { - java.awt.Font awtFont = super.getFont(); - FontRenderContext frc = super.getFontRenderContext(); - GlyphVector gv = awtFont.createGlyphVector(frc, s); - Shape glyphOutline = gv.getOutline(x, y); - fill(glyphOutline); - } - - /** - * Draw a string to the PostScript document. The text is painted using - * text operations. - * @param s the string to draw - * @param x the x position - * @param y the y position - */ - public void drawStringAsText(String s, float x, float y) { - preparePainting(); - log.trace("drawString('" + s + "', " + x + ", " + y + ")"); - try { - if (this.overrideFont == null) { - java.awt.Font awtFont = getFont(); - this.font = createFont(awtFont); - } else { - this.font = this.overrideFont; - this.overrideFont = null; - } - - //Color and Font state - establishColor(getColor()); - establishCurrentFont(); - - //Clip - Shape imclip = getClip(); - writeClip(imclip); - - gen.saveGraphicsState(); - - //Prepare correct transformation - AffineTransform trans = getTransform(); - gen.concatMatrix(trans); - gen.writeln(gen.formatDouble(x) + " " - + gen.formatDouble(y) + " moveto "); - gen.writeln("1 -1 scale"); - - StringBuffer sb = new StringBuffer("("); - escapeText(s, sb); - sb.append(") t "); - - gen.writeln(sb.toString()); - - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - private void escapeText(final String text, StringBuffer target) { - final int l = text.length(); - for (int i = 0; i < l; i++) { - final char ch = text.charAt(i); - final char mch = this.font.mapChar(ch); - PSGenerator.escapeChar(mch, target); - } - } - - private Font createFont(java.awt.Font f) { - String fontFamily = f.getFamily(); - if (fontFamily.equals("sanserif")) { - fontFamily = "sans-serif"; - } - int fontSize = 1000 * f.getSize(); - String style = f.isItalic() ? "italic" : "normal"; - int weight = f.isBold() ? Font.BOLD : Font.NORMAL; - - FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight); - if (triplet == null) { - triplet = fontInfo.findAdjustWeight("sans-serif", style, weight); - } - return fontInfo.getFontInstance(triplet, fontSize); - } - - private void establishCurrentFont() throws IOException { - if ((currentFontName != this.font.getFontName()) - || (currentFontSize != this.font.getFontSize())) { - gen.writeln(this.font.getFontName() + " " + this.font.getFontSize() + " F"); - currentFontName = this.font.getFontName(); - currentFontSize = this.font.getFontSize(); - } - } - - /** - * 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) { - preparePainting(); - log.warn("NYI: drawString(AttributedCharacterIterator)"); - /* - try { - gen.writeln("BT"); - Shape imclip = getClip(); - writeClip(imclip); - establishColor(getColor()); - - 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) { - preparePainting(); - try { - gen.saveGraphicsState(); - - AffineTransform trans = getTransform(); - boolean newTransform = gen.getCurrentState().checkTransform(trans) - && !trans.isIdentity(); - - if (newTransform) { - gen.concatMatrix(trans); - } - Shape imclip = getClip(); - writeClip(imclip); - - establishColor(getColor()); - - applyPaint(getPaint(), true); - - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - doDrawing(true, false, - iter.getWindingRule() == PathIterator.WIND_EVEN_ODD); - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - /** - * Commits a painting operation. - * @param fill filling - * @param stroke stroking - * @param nonzero true if the non-zero winding rule should be used when filling - * @exception IOException In case of an I/O problem - */ - protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) - throws IOException { - preparePainting(); - if (fill) { - if (stroke) { - if (!nonzero) { - gen.writeln("gsave fill grestore stroke"); - } else { - gen.writeln("gsave eofill grestore stroke"); - } - } else { - if (!nonzero) { - gen.writeln("fill"); - } else { - gen.writeln("eofill"); - } - } - } else { - // if(stroke) - gen.writeln("stroke"); - } - } - - /** - * Returns the device configuration associated with this - * Graphics2D. - * @return the device configuration - */ - public GraphicsConfiguration getDeviceConfiguration() { - 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 overriding font. - * @param font Font to set - */ - public void setOverrideFont(Font font) { - this.overrideFont = font; - } - - /** - * 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(java.awt.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) { - log.warn("NYI: 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) { - log.warn("NYI: copyArea"); - } - - /* --- for debugging - public void transform(AffineTransform tx) { - System.out.println("transform(" + toArray(tx) + ")"); - super.transform(zx); - } - - public void scale(double sx, double sy) { - System.out.println("scale(" + sx + ", " + sy + ")"); - super.scale(sx, sy); - } - - public void translate(double tx, double ty) { - System.out.println("translate(double " + tx + ", " + ty + ")"); - super.translate(tx, ty); - } - - public void translate(int tx, int ty) { - System.out.println("translate(int " + tx + ", " + ty + ")"); - super.translate(tx, ty); - } - */ - -} diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java index d54c87b8c..1464f4463 100644 --- a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 The Apache Software Foundation. + * Copyright 2005-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,8 @@ import java.io.IOException; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.Graphics2DImagePainter; import org.apache.fop.render.RendererContext; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.ps.PSGenerator; /** * Graphics2DAdapter implementation for PostScript. @@ -75,7 +77,7 @@ public class PSGraphics2DAdapter implements Graphics2DAdapter { final boolean textAsShapes = false; PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen); - graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); + graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); AffineTransform transform = new AffineTransform(); // scale to viewbox transform.translate(fx, fy); diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java index bd3736eb5..9d6314f9d 100644 --- a/src/java/org/apache/fop/render/ps/PSImageUtils.java +++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java @@ -19,29 +19,20 @@ package org.apache.fop.render.ps; import java.awt.Dimension; -import java.awt.color.ColorSpace; import java.awt.geom.Rectangle2D; -import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; import java.io.IOException; -import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.image.EPSImage; import org.apache.fop.image.FopImage; import org.apache.fop.image.JpegImage; -import org.apache.fop.util.ASCII85OutputStream; -import org.apache.fop.util.Finalizable; -import org.apache.fop.util.FlateEncodeOutputStream; -import org.apache.fop.util.RunLengthEncodeOutputStream; +import org.apache.xmlgraphics.ps.PSGenerator; /** * Utility code for rendering images in PostScript. */ -public class PSImageUtils { +public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils { /** logging instance */ protected static Log log = LogFactory.getLog(PSImageUtils.class); @@ -85,187 +76,6 @@ public class PSImageUtils { img.getColorSpace(), gen); } - private static void writeImage(byte[] img, - Dimension imgDim, String imgName, - Rectangle2D targetRect, - boolean isJPEG, ColorSpace colorSpace, - PSGenerator gen) throws IOException { - boolean iscolor = colorSpace.getType() != ColorSpace.CS_GRAY; - - gen.saveGraphicsState(); - gen.writeln(gen.formatDouble(targetRect.getX()) + " " - + gen.formatDouble(targetRect.getY()) + " translate"); - gen.writeln(gen.formatDouble(targetRect.getWidth()) + " " - + gen.formatDouble(targetRect.getHeight()) + " scale"); - - gen.commentln("%FOPBeginBitmap: " + imgName); - if (colorSpace.getType() == ColorSpace.TYPE_CMYK) { - gen.writeln("/DeviceCMYK setcolorspace"); - } else if (colorSpace.getType() == ColorSpace.CS_GRAY) { - gen.writeln("/DeviceGray setcolorspace"); - } else { - gen.writeln("/DeviceRGB setcolorspace"); - } - - gen.writeln("{{"); - // Template: (RawData is used for the EOF signal only) - // gen.write("/RawData currentfile filter def"); - // gen.write("/Data RawData [...] def"); - if (isJPEG) { - gen.writeln("/RawData currentfile /ASCII85Decode filter def"); - gen.writeln("/Data RawData << >> /DCTDecode filter def"); - } else { - if (gen.getPSLevel() >= 3) { - gen.writeln("/RawData currentfile /ASCII85Decode filter def"); - gen.writeln("/Data RawData /FlateDecode filter def"); - } else { - gen.writeln("/RawData currentfile /ASCII85Decode filter def"); - gen.writeln("/Data RawData /RunLengthDecode filter def"); - } - } - gen.writeln("<<"); - gen.writeln(" /ImageType 1"); - gen.writeln(" /Width " + imgDim.width); - gen.writeln(" /Height " + imgDim.height); - gen.writeln(" /BitsPerComponent 8"); - if (colorSpace.getType() == ColorSpace.TYPE_CMYK) { - if (false /*TODO img.invertImage()*/) { - gen.writeln(" /Decode [1 0 1 0 1 0 1 0]"); - } else { - gen.writeln(" /Decode [0 1 0 1 0 1 0 1]"); - } - } else if (iscolor) { - gen.writeln(" /Decode [0 1 0 1 0 1]"); - } else { - gen.writeln(" /Decode [0 1]"); - } - // Setup scanning for left-to-right and top-to-bottom - gen.writeln(" /ImageMatrix [" + imgDim.width + " 0 0 " - + imgDim.height + " 0 0]"); - - gen.writeln(" /DataSource Data"); - gen.writeln(">>"); - gen.writeln("image"); - /* the following two lines could be enabled if something still goes wrong - * gen.write("Data closefile"); - * gen.write("RawData flushfile"); - */ - gen.writeln("} stopped {handleerror} if"); - gen.writeln(" RawData flushfile"); - gen.writeln("} exec"); - - OutputStream out = gen.getOutputStream(); - out = new ASCII85OutputStream(out); - if (isJPEG) { - //nop - } else { - if (gen.getPSLevel() >= 3) { - out = new FlateEncodeOutputStream(out); - } else { - out = new RunLengthEncodeOutputStream(out); - } - } - out.write(img); - if (out instanceof Finalizable) { - ((Finalizable)out).finalizeStream(); - } else { - out.flush(); - } - - gen.writeln(""); - gen.commentln("%FOPEndBitmap"); - gen.restoreGraphicsState(); - } - - /** - * Renders a bitmap image to PostScript. - * @param img image to render - * @param x x position - * @param y y position - * @param w width - * @param h height - * @param gen PS generator - * @throws IOException In case of an I/O problem while rendering the image - */ - public static void renderBitmapImage(RenderedImage img, - float x, float y, float w, float h, PSGenerator gen) - throws IOException { - byte[] imgmap = getBitmapBytes(img); - - String imgName = img.getClass().getName(); - Dimension imgDim = new Dimension(img.getWidth(), img.getHeight()); - Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h); - boolean isJPEG = false; - writeImage(imgmap, imgDim, imgName, targetRect, isJPEG, - img.getColorModel().getColorSpace(), gen); - } - - private static byte[] getBitmapBytes(RenderedImage img) { - int[] tmpMap = getRGB(img, 0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); - // Should take care of the ColorSpace and bitsPerPixel - byte[] bitmaps = new byte[img.getWidth() * img.getHeight() * 3]; - for (int y = 0, my = img.getHeight(); y < my; y++) { - for (int x = 0, mx = img.getWidth(); x < mx; x++) { - int p = tmpMap[y * mx + x]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; - int b = (p) & 0xFF; - bitmaps[3 * (y * mx + x)] = (byte)(r & 0xFF); - bitmaps[3 * (y * mx + x) + 1] = (byte)(g & 0xFF); - bitmaps[3 * (y * mx + x) + 2] = (byte)(b & 0xFF); - } - } - return bitmaps; - } - - public static int[] getRGB(RenderedImage img, - int startX, int startY, int w, int h, - int[] rgbArray, int offset, int scansize) { - Raster raster = img.getData(); - int yoff = offset; - int off; - Object data; - int nbands = raster.getNumBands(); - int dataType = raster.getDataBuffer().getDataType(); - switch (dataType) { - case DataBuffer.TYPE_BYTE: - data = new byte[nbands]; - break; - case DataBuffer.TYPE_USHORT: - data = new short[nbands]; - break; - case DataBuffer.TYPE_INT: - data = new int[nbands]; - break; - case DataBuffer.TYPE_FLOAT: - data = new float[nbands]; - break; - case DataBuffer.TYPE_DOUBLE: - data = new double[nbands]; - break; - default: - throw new IllegalArgumentException("Unknown data buffer type: "+ - dataType); - } - - if (rgbArray == null) { - rgbArray = new int[offset+h*scansize]; - } - - ColorModel colorModel = img.getColorModel(); - for (int y = startY; y < startY+h; y++, yoff+=scansize) { - off = yoff; - for (int x = startX; x < startX+w; x++) { - rgbArray[off++] = colorModel.getRGB(raster.getDataElements(x, - y, - data)); - } - } - - return rgbArray; - - } - public static void renderEPS(EPSImage img, float x, float y, float w, float h, PSGenerator gen) { @@ -291,51 +101,4 @@ public class PSImageUtils { } } - /** - * Places an EPS file in the PostScript stream. - * @param rawEPS byte array containing the raw EPS data - * @param name name for the EPS document - * @param x x-coordinate of viewport in millipoints - * @param y y-coordinate of viewport in millipoints - * @param w width of viewport in millipoints - * @param h height of viewport in millipoints - * @param bboxx x-coordinate of EPS bounding box in points - * @param bboxy y-coordinate of EPS bounding box in points - * @param bboxw width of EPS bounding box in points - * @param bboxh height of EPS bounding box in points - * @param gen the PS generator - * @throws IOException in case an I/O error happens during output - */ - public static void renderEPS(byte[] rawEPS, String name, - float x, float y, float w, float h, - float bboxx, float bboxy, float bboxw, float bboxh, - PSGenerator gen) throws IOException { - gen.notifyResourceUsage(PSProcSets.EPS_PROCSET, false); - gen.writeln("%FOPBeginEPS: " + name); - gen.writeln("BeginEPSF"); - - gen.writeln(gen.formatDouble(x) + " " + gen.formatDouble(y) + " translate"); - gen.writeln("0 " + gen.formatDouble(h) + " translate"); - gen.writeln("1 -1 scale"); - float sx = w / bboxw; - float sy = h / bboxh; - if (sx != 1 || sy != 1) { - gen.writeln(gen.formatDouble(sx) + " " + gen.formatDouble(sy) + " scale"); - } - if (bboxx != 0 || bboxy != 0) { - gen.writeln(gen.formatDouble(-bboxx) + " " + gen.formatDouble(-bboxy) + " translate"); - } - gen.writeln(gen.formatDouble(bboxy) + " " + gen.formatDouble(bboxy) - + " " + gen.formatDouble(bboxw) + " " + gen.formatDouble(bboxh) + " re clip"); - gen.writeln("newpath"); - - PSResource res = new PSResource(PSResource.TYPE_FILE, name); - gen.notifyResourceUsage(res, false); - gen.writeDSCComment(DSCConstants.BEGIN_DOCUMENT, res.getName()); - gen.writeByteArr(rawEPS); - gen.writeDSCComment(DSCConstants.END_DOCUMENT); - gen.writeln("EndEPSF"); - gen.writeln("%FOPEndEPS"); - } - } diff --git a/src/java/org/apache/fop/render/ps/PSProcSets.java b/src/java/org/apache/fop/render/ps/PSProcSets.java deleted file mode 100644 index 56ee8fd0e..000000000 --- a/src/java/org/apache/fop/render/ps/PSProcSets.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -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 FOP Development Team - * @version $Id: PSProcSets.java,v 1.3 2003/03/11 08:42:24 jeremias Exp $ - */ -public final class PSProcSets { - - /** the standard FOP procset */ - public static final PSResource STD_PROCSET = new StdProcSet(); - /** the EPS FOP procset */ - public static final PSResource EPS_PROCSET = new EPSProcSet(); - - private static class StdProcSet extends PSResource { - - public StdProcSet() { - super("procset", "Apache FOP Std ProcSet"); - } - - public void writeTo(PSGenerator gen) throws IOException { - gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, - new Object[] {"procset", getName(), "1.0", "0"}); - gen.writeDSCComment(DSCConstants.VERSION, - new Object[] {"1.0", "0"}); - gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2001-2003 " - + "The Apache Software Foundation. All rights reserved."); - gen.writeDSCComment(DSCConstants.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("/A/ashow ld"); - gen.writeln("/cp/closepath ld"); - - gen.writeln("/re {4 2 roll M"); //define rectangle - gen.writeln("1 index 0 rlineto"); - gen.writeln("0 exch rlineto"); - gen.writeln("neg 0 rlineto"); - gen.writeln("cp } bd"); - - 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.writeDSCComment(DSCConstants.END_RESOURCE); - } - - } - - private static class EPSProcSet extends PSResource { - - public EPSProcSet() { - super("procset", "Apache FOP EPS ProcSet"); - } - - public void writeTo(PSGenerator gen) throws IOException { - gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, - new Object[] {"procset", getName(), "1.0", "0"}); - gen.writeDSCComment(DSCConstants.VERSION, - new Object[] {"1.0", "0"}); - gen.writeDSCComment(DSCConstants.COPYRIGHT, "Copyright 2002-2003 " - + "The Apache Software Foundation. All rights reserved."); - gen.writeDSCComment(DSCConstants.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.writeDSCComment(DSCConstants.END_RESOURCE); - } - - } - - /** - * 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 void writeFOPStdProcSet(PSGenerator gen) throws IOException { - ((StdProcSet)STD_PROCSET).writeTo(gen); - } - - - /** - * 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 void writeFOPEPSProcSet(PSGenerator gen) throws IOException { - ((EPSProcSet)EPS_PROCSET).writeTo(gen); - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index dab429a13..a7e54b1e8 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -70,6 +70,12 @@ import org.apache.fop.render.RendererContext; import org.apache.fop.render.ps.extensions.PSSetupCode; import org.apache.fop.util.CharUtilities; +import org.apache.xmlgraphics.ps.DSCConstants; +import org.apache.xmlgraphics.ps.PSGenerator; +import org.apache.xmlgraphics.ps.PSProcSets; +import org.apache.xmlgraphics.ps.PSResource; +import org.apache.xmlgraphics.ps.PSState; + import org.w3c.dom.Document; /** diff --git a/src/java/org/apache/fop/render/ps/PSResource.java b/src/java/org/apache/fop/render/ps/PSResource.java deleted file mode 100644 index b68bcaf6d..000000000 --- a/src/java/org/apache/fop/render/ps/PSResource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -/** - * Represents a PostScript resource (file, font, procset etc.). - */ -public class PSResource { - - /** a file resource */ - public static final String TYPE_FILE = "file"; - /** a font resource */ - public static final String TYPE_FONT = "font"; - /** a procset resource */ - public static final String TYPE_PROCSET = "procset"; - - private String type; - private String name; - - /** - * Main constructor - * @param type type of the resource - * @param name name of the resource - */ - public PSResource(String type, String name) { - this.type = type; - this.name = name; - } - - /** @return the type of the resource */ - public String getType() { - return this.type; - } - - /** @return the name of the resource */ - public String getName() { - return this.name; - } - - /** @return the specification as defined in DSC v3.0 spec. */ - public String getResourceSpecification() { - StringBuffer sb = new StringBuffer(); - sb.append(getType()).append(" ").append(PSGenerator.convertStringToDSC(getName())); - return sb.toString(); - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index e54bc4b49..e0ea029ad 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,8 @@ import org.apache.fop.render.Renderer; import org.apache.fop.render.XMLHandler; import org.apache.fop.render.RendererContext; import org.apache.fop.svg.SVGUserAgent; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.ps.PSGenerator; // Commons-Logging import org.apache.commons.logging.Log; @@ -251,10 +253,16 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { context.getUserAgent().getSourcePixelUnitToMillimeter(), new AffineTransform()); + PSGraphics2D graphics = new PSGraphics2D(strokeText, gen); + graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + GVTBuilder builder = new GVTBuilder(); + NativeTextHandler nativeTextHandler = null; BridgeContext ctx = new BridgeContext(ua); if (!strokeText) { - PSTextPainter textPainter = new PSTextPainter(psInfo.getFontInfo()); + nativeTextHandler = new NativeTextHandler(graphics, psInfo.getFontInfo()); + graphics.setCustomTextHandler(nativeTextHandler); + PSTextPainter textPainter = new PSTextPainter(nativeTextHandler); ctx.setTextPainter(textPainter); PSTextElementBridge tBridge = new PSTextElementBridge(textPainter); ctx.putBridge(tBridge); @@ -306,9 +314,6 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { gen.concatMatrix(vals); }*/ - final boolean textAsShapes = false; - PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen); - graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); AffineTransform transform = new AffineTransform(); // scale to viewbox transform.translate(xOffset, yOffset); diff --git a/src/java/org/apache/fop/render/ps/PSState.java b/src/java/org/apache/fop/render/ps/PSState.java deleted file mode 100644 index 7421c5f28..000000000 --- a/src/java/org/apache/fop/render/ps/PSState.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.io.IOException; -import java.io.Serializable; -import java.util.List; -import java.awt.Color; -import java.awt.geom.AffineTransform; - -/** - * This class holds the current state of the PostScript interpreter. - * - * @author Apache XML FOP Development Team - * @version $Id$ - */ -public class PSState implements Serializable { - - /** Default for setdash */ - public static final String DEFAULT_DASH = "[] 0"; - /** Default color in PostScript */ - public static final Color DEFAULT_RGB_COLOR = Color.black; - - private AffineTransform transform = new AffineTransform(); - private List transformConcatList = new java.util.ArrayList(); - - private int linecap = 0; - private double linewidth = 1.0f; - private String dashpattern = DEFAULT_DASH; - private Color rgbColor = DEFAULT_RGB_COLOR; - - //Font state - private String fontname; - private float fontsize; - - /** - * Default constructor - */ - public PSState() { - //nop - } - - /** - * Copy constructor - * @param org the original to copy from - * @param copyTransforms true if the list of matrix concats should be cloned, too - */ - public PSState(PSState org, boolean copyTransforms) { - this.transform = (AffineTransform)org.transform.clone(); - if (copyTransforms) { - this.transformConcatList.addAll(org.transformConcatList); - } - this.linecap = org.linecap; - this.linewidth = org.linewidth; - this.dashpattern = org.dashpattern; - this.rgbColor = org.rgbColor; - this.fontname = org.fontname; - this.fontsize = org.fontsize; - } - - /** - * Returns the transform. - * @return the current transformation matrix - */ - public AffineTransform getTransform() { - return this.transform; - } - - /** - * 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(this.transform); - } - - /** - * Concats the given transformation matrix with the current one. - * @param transform The new transformation matrix - */ - public void concatMatrix(AffineTransform transform) { - this.transformConcatList.add(transform); - this.transform.concatenate(transform); - } - - /** - * Establishes the specified line cap. - * @param value line cap (0, 1 or 2) as defined by the setlinecap command - * @return true if the line cap changed compared to the previous setting - */ - public boolean useLineCap(int value) { - if (linecap != value) { - linecap = value; - return true; - } else { - return false; - } - } - - /** - * Establishes the specified line width. - * @param value line width as defined by the setlinewidth command - * @return true if the line width changed compared to the previous setting - */ - public boolean useLineWidth(double value) { - if (linewidth != value) { - linewidth = value; - return true; - } else { - return false; - } - } - - /** - * Establishes the specified dash. - * @param pattern dash pattern as defined by the setdash command - * @return true if the dash pattern changed compared to the previous setting - */ - public boolean useDash(String pattern) { - if (!dashpattern.equals(pattern)) { - dashpattern = pattern; - return true; - } else { - return false; - } - } - - /** - * Establishes the specified color (RGB). - * @param value color as defined by the setrgbcolor command - * @return true if the color changed compared to the previous setting - */ - public boolean useColor(Color value) { - if (!rgbColor.equals(value)) { - rgbColor = value; - return true; - } else { - return false; - } - } - - /** - * Establishes the specified font and size. - * @param name name of the font for the "F" command (see FOP Std Proc Set) - * @param size size of the font - * @return true if the font changed compared to the previous setting - */ - public boolean useFont(String name, float size) { - if (name == null) { - throw new NullPointerException("font name must not be null"); - } - if (fontname == null || !fontname.equals(name) || fontsize != size) { - fontname = name; - fontsize = size; - return true; - } else { - return false; - } - } - - /** - * Reestablishes the graphics state represented by this instance by issueing the - * necessary commands. - * @param gen The generator to use for output - * @exception IOException In case of an I/O problem - */ - public void reestablish(PSGenerator gen) throws IOException { - for (int i = 0, len = transformConcatList.size(); i < len; i++) { - gen.concatMatrix((AffineTransform)transformConcatList.get(i)); - } - gen.useLineCap(linecap); - gen.useLineWidth(linewidth); - gen.useDash(dashpattern); - gen.useRGBColor(rgbColor); - if (fontname != null) { - gen.useFont(fontname, fontsize); - } - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java index db654adb2..c42f3647b 100644 --- a/src/java/org/apache/fop/render/ps/PSTextPainter.java +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -31,9 +31,15 @@ import java.awt.Shape; import java.awt.Paint; import java.awt.Stroke; import java.awt.Color; +import java.io.IOException; import java.util.List; import java.util.Iterator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; + import org.apache.batik.dom.svg.SVGOMTextElement; import org.apache.batik.gvt.text.Mark; import org.apache.batik.gvt.TextPainter; @@ -42,8 +48,6 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; import org.apache.batik.gvt.text.TextPaintInfo; import org.apache.batik.gvt.font.GVTFontFamily; import org.apache.batik.gvt.renderer.StrokingTextPainter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -68,7 +72,8 @@ public class PSTextPainter implements TextPainter { /** the logger for this class */ protected Log log = LogFactory.getLog(PSTextPainter.class); - private FontInfo fontInfo; + private NativeTextHandler nativeTextHandler; + //private FontInfo fontInfo; /** * Use the stroking text painter to get the bounds and shape. @@ -79,10 +84,10 @@ public class PSTextPainter implements TextPainter { /** * Create a new PS text painter with the given font information. - * @param fontInfo the FontInfo object + * @param nativeTextHandler the NativeTextHandler instance used for text painting */ - public PSTextPainter(FontInfo fontInfo) { - this.fontInfo = fontInfo; + public PSTextPainter(NativeTextHandler nativeTextHandler) { + this.nativeTextHandler = nativeTextHandler; } /** @@ -188,7 +193,9 @@ public class PSTextPainter implements TextPainter { Object rcDel = aci.getAttribute( GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER); - if (!(rcDel instanceof SVGOMTextElement)) { + //Batik 1.6 returns null here which makes it impossible to determine whether this can + //be painted or not, i.e. fall back to stroking. :-( + if (/*rcDel != null &&*/ !(rcDel instanceof SVGOMTextElement)) { log.trace("-> spans found"); hasunsupported = true; //Filter spans } @@ -307,15 +314,17 @@ public class PSTextPainter implements TextPainter { } //Finally draw text - if (g2d instanceof PSGraphics2D) { - ((PSGraphics2D) g2d).setOverrideFont(font); - } + nativeTextHandler.setOverrideFont(font); try { - g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); - } finally { - if (g2d instanceof PSGraphics2D) { - ((PSGraphics2D) g2d).setOverrideFont(null); + try { + nativeTextHandler.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); + } catch (IOException ioe) { + if (g2d instanceof PSGraphics2D) { + ((PSGraphics2D)g2d).handleIOException(ioe); + } } + } finally { + nativeTextHandler.setOverrideFont(null); } loc.setLocation(loc.getX() + (double)advance, loc.getY()); return loc; @@ -370,6 +379,7 @@ public class PSTextPainter implements TextPainter { int weight = getWeight(aci); boolean found = false; + FontInfo fontInfo = nativeTextHandler.getFontInfo(); String fontFamily = null; List gvtFonts = (List) aci.getAttribute( GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); diff --git a/src/java/org/apache/fop/render/ps/PSTranscoder.java b/src/java/org/apache/fop/render/ps/PSTranscoder.java index 62104ca26..5289f8272 100644 --- a/src/java/org/apache/fop/render/ps/PSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/PSTranscoder.java @@ -18,6 +18,8 @@ package org.apache.fop.render.ps; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.PSDocumentGraphics2D; /** * This class enables to transcode an input to a PostScript document. @@ -44,7 +46,6 @@ package org.apache.fop.render.ps; * millimeter conversion factor. * * @author Keiron Liddle - * @author Jeremias Maerki * @version $Id$ */ public class PSTranscoder extends AbstractPSTranscoder { @@ -56,6 +57,7 @@ public class PSTranscoder extends AbstractPSTranscoder { super(); } + /** @see AbstractPSTranscoder#createDocumentGraphics2D() */ protected AbstractPSDocumentGraphics2D createDocumentGraphics2D() { return new PSDocumentGraphics2D(false); } diff --git a/src/java/org/apache/fop/util/ASCII85Constants.java b/src/java/org/apache/fop/util/ASCII85Constants.java deleted file mode 100644 index e8e3a8bd1..000000000 --- a/src/java/org/apache/fop/util/ASCII85Constants.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -/** - * This interface defines constants used by the ASCII85 filters. - * - * @author Jeremias Maerki - * @version $Id$ - */ -public interface ASCII85Constants { - - /** Special character "z" stands for four NULL bytes (short-cut for !!!!!) */ - public static final int ZERO = 0x7A; //"z" - /** ZERO as a byte array */ - public static final byte[] ZERO_ARRAY = {(byte)ZERO}; - /** The start index for ASCII85 characters (!) */ - public static final int START = 0x21; //"!" - /** The end index for ASCII85 characters (u) */ - public static final int END = 0x75; //"u" - /** The EOL indicator (LF) */ - public static final int EOL = 0x0A; //"\n" - /** The EOD (end of data) indicator */ - public static final byte[] EOD = {0x7E, 0x3E}; //"~>" - - /** Array of powers of 85 (4, 3, 2, 1, 0) */ - public static final long POW85[] = new long[] {85 * 85 * 85 * 85, - 85 * 85 * 85, - 85 * 85, - 85, - 1}; - - /* - public static final long BASE85_4 = 85; - public static final long BASE85_3 = BASE85_4 * BASE85_4; - public static final long BASE85_2 = BASE85_3 * BASE85_4; - public static final long BASE85_1 = BASE85_2 * BASE85_4; - */ - -} - - diff --git a/src/java/org/apache/fop/util/ASCII85InputStream.java b/src/java/org/apache/fop/util/ASCII85InputStream.java deleted file mode 100644 index d9b3fae91..000000000 --- a/src/java/org/apache/fop/util/ASCII85InputStream.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.InputStream; -import java.io.IOException; - -/** - * This class applies a ASCII85 decoding to the stream. - *

    - * The class is derived from InputStream instead of FilteredInputStream because - * we can use the read(byte[], int, int) method from InputStream which simply - * delegates to read(). This makes the implementation easier. - *

    - * The filter is described in chapter 3.13.3 of the PostScript Language - * Reference (third edition). - * - * @version $Id$ - */ -public class ASCII85InputStream extends InputStream - implements ASCII85Constants { - - private InputStream in; - private boolean eodReached = false; - private int[] b = new int[4]; //decoded - private int bSize = 0; - private int bIndex = 0; - - /** @see java.io.FilterInputStream **/ - public ASCII85InputStream(InputStream in) { - super(); - this.in = in; - } - - /** @see java.io.FilterInputStream **/ - public int read() throws IOException { - //Check if we need to read the next tuple - if (bIndex >= bSize) { - if (eodReached) { - return -1; - } - readNextTuple(); - if (bSize == 0) { - if (!eodReached) { - throw new IllegalStateException("Internal error"); - } - return -1; - } - } - int result = b[bIndex]; - result = (result < 0 ? 256 + result : result); - bIndex++; - return result; - } - - private int filteredRead() throws IOException { - int buf; - while (true) { - buf = in.read(); - switch (buf) { - case 0: //null - case 9: //tab - case 10: //LF - case 12: //FF - case 13: //CR - case 32: //space - continue; //ignore - case ZERO: - case 126: //= EOD[0] = '~' - return buf; - default: - if ((buf >= START) && (buf <= END)) { - return buf; - } else { - throw new IOException("Illegal character detected: " + buf); - } - } - } - } - - private void handleEOD() throws IOException { - final int buf = in.read(); - if (buf != EOD[1]) { - throw new IOException("'>' expected after '~' (EOD)"); - } - eodReached = true; - bSize = 0; - bIndex = 0; - } - - private void readNextTuple() throws IOException { - int buf; - long tuple = 0; - //Read ahead and check for special "z" - buf = filteredRead(); - if (buf == ZERO) { - java.util.Arrays.fill(b, 0); - bSize = 4; - bIndex = 0; - } else if (buf == EOD[0]) { - handleEOD(); - } else { - int cIndex = 0; - tuple = (buf - START) * POW85[cIndex]; - cIndex++; - while (cIndex < 5) { - buf = filteredRead(); - if (buf == EOD[0]) { - handleEOD(); - break; - } else if (buf == ZERO) { - //Violation 2 - throw new IOException("Illegal 'z' within tuple"); - } else { - tuple += (buf - START) * POW85[cIndex]; - cIndex++; - } - } - int cSize = cIndex; - if (cSize == 1) { - //Violation 3 - throw new IOException("Only one character in tuple"); - } - //Handle optional, trailing, incomplete tuple - while (cIndex < 5) { - tuple += POW85[cIndex - 1]; - cIndex++; - } - if (tuple > (2L << 31) - 1) { - //Violation 1 - throw new IOException("Illegal tuple (> 2^32 - 1)"); - } - //Convert tuple - b[0] = (byte)((tuple >> 24) & 0xFF); - b[1] = (byte)((tuple >> 16) & 0xFF); - b[2] = (byte)((tuple >> 8) & 0xFF); - b[3] = (byte)((tuple) & 0xFF); - bSize = cSize - 1; - bIndex = 0; - } - } - -} - - diff --git a/src/java/org/apache/fop/util/ASCII85OutputStream.java b/src/java/org/apache/fop/util/ASCII85OutputStream.java deleted file mode 100644 index 02bc613dc..000000000 --- a/src/java/org/apache/fop/util/ASCII85OutputStream.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.OutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -/** - * This class applies a ASCII85 encoding to the stream. - * - * @version $Id$ - */ -public class ASCII85OutputStream extends FilterOutputStream - implements ASCII85Constants, Finalizable { - - 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; - } - } - - /* UNUSED ATM - 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, false); - } - - private void checkedWrite(byte[] buf, boolean nosplit) throws IOException { - checkedWrite(buf, buf.length, nosplit); - } - - private void checkedWrite(byte[] buf , int len) throws IOException { - checkedWrite(buf, len, false); - } - - private void checkedWrite(byte[] buf , int len, boolean nosplit) throws IOException { - if (posinline + len > 80) { - int firstpart = (nosplit ? 0 : 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 - / POW85[0]) & 0xFF); - byte c2 = - (byte)(((word - (c1 * POW85[0])) - / POW85[1]) & 0xFF); - byte c3 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1])) - / POW85[2]) & 0xFF); - byte c4 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1]) - - (c3 * POW85[2])) - / POW85[3]) & 0xFF); - byte c5 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1]) - - (c3 * POW85[2]) - - (c4 * POW85[3]))) - & 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 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, true); - - 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/util/ASCIIHexOutputStream.java b/src/java/org/apache/fop/util/ASCIIHexOutputStream.java deleted file mode 100644 index d2ac48a3e..000000000 --- a/src/java/org/apache/fop/util/ASCIIHexOutputStream.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -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$ - */ -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 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/util/ContentHandlerFactoryRegistry.java b/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java index 5fd68fd2b..3d95d91a3 100644 --- a/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java +++ b/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java @@ -24,7 +24,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.util.Service; +import org.apache.xmlgraphics.util.Service; /** * This class holds references to various XML handlers used by FOP. It also @@ -101,12 +101,13 @@ public class ContentHandlerFactoryRegistry { Iterator providers = Service.providers(ContentHandlerFactory.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + ContentHandlerFactory factory = (ContentHandlerFactory)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding ContentHandlerFactory: " + str); + log.debug("Dynamically adding ContentHandlerFactory: " + + factory.getClass().getName()); } - addContentHandlerFactory(str); + addContentHandlerFactory(factory); } catch (IllegalArgumentException e) { log.error("Error while adding ContentHandlerFactory", e); } diff --git a/src/java/org/apache/fop/util/Finalizable.java b/src/java/org/apache/fop/util/Finalizable.java deleted file mode 100644 index 365f0cae6..000000000 --- a/src/java/org/apache/fop/util/Finalizable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -/** - * 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$ - */ -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/util/FlateEncodeOutputStream.java b/src/java/org/apache/fop/util/FlateEncodeOutputStream.java deleted file mode 100644 index 9789929e4..000000000 --- a/src/java/org/apache/fop/util/FlateEncodeOutputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -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$ - */ -public class FlateEncodeOutputStream extends java.util.zip.DeflaterOutputStream - implements Finalizable { - - - /** @see java.util.zip.DeflaterOutputStream **/ - public FlateEncodeOutputStream(OutputStream out) { - super(out); - } - - - /** @see Finalizable **/ - public void finalizeStream() throws IOException { - finish(); - flush(); - if (out instanceof Finalizable) { - ((Finalizable)out).finalizeStream(); - } - } - -} - - diff --git a/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java b/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java deleted file mode 100644 index f3cd225be..000000000 --- a/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -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$ - */ -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 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/util/Service.java b/src/java/org/apache/fop/util/Service.java deleted file mode 100644 index 717b0f47f..000000000 --- a/src/java/org/apache/fop/util/Service.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -//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. - */ -public 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(); - - // log.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(); - //log.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; - } - // log.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(); - } - - } \ No newline at end of file diff --git a/src/java/org/apache/fop/util/SubInputStream.java b/src/java/org/apache/fop/util/SubInputStream.java deleted file mode 100644 index 83b146402..000000000 --- a/src/java/org/apache/fop/util/SubInputStream.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * This class is a FilterInputStream descendant that reads from an underlying InputStream - * up to a defined number of bytes or the end of the underlying stream. Closing this InputStream - * will not result in the underlying InputStream to be closed, too. - *

    - * This InputStream can be used to read chunks from a larger file of which the length is - * known in advance. - */ -public class SubInputStream extends FilterInputStream { - - /** Indicates the number of bytes remaning to be read from the underlying InputStream. */ - private long bytesToRead; - - /** - * Creates a new SubInputStream. - * @param in the InputStream to read from - * @param maxLen the maximum number of bytes to read from the underlying InputStream until - * the end-of-file is signalled. - */ - public SubInputStream(InputStream in, long maxLen) { - super(in); - this.bytesToRead = maxLen; - } - - /** @see java.io.InputStream#read() */ - public int read() throws IOException { - if (bytesToRead > 0) { - int result = super.read(); - if (result <= 0) { - bytesToRead--; - return result; - } else { - return -1; - } - } else { - return -1; - } - } - - /** @see java.io.InputStream#read(byte[], int, int) */ - public int read(byte[] b, int off, int len) throws IOException { - if (bytesToRead == 0) { - return -1; - } - int effRead = (int)Math.min(bytesToRead, len); - //cast to int is safe because len can never be bigger than Integer.MAX_VALUE - - int result = super.read(b, off, effRead); - if (result >= 0) { - bytesToRead -= result; - } - return result; - } - - /** @see java.io.InputStream#skip(long) */ - public long skip(long n) throws IOException { - long effRead = Math.min(bytesToRead, n); - long result = super.skip(effRead); - bytesToRead -= result; - return result; - } - - /** @see java.io.InputStream#close() */ - public void close() throws IOException { - //Don't close the underlying InputStream!!! - this.bytesToRead = 0; - } -} diff --git a/test/java/org/apache/fop/UtilityCodeTestSuite.java b/test/java/org/apache/fop/UtilityCodeTestSuite.java index 86b086c53..cce534e92 100644 --- a/test/java/org/apache/fop/UtilityCodeTestSuite.java +++ b/test/java/org/apache/fop/UtilityCodeTestSuite.java @@ -20,8 +20,6 @@ package org.apache.fop; import org.apache.fop.traits.BorderPropsTestCase; import org.apache.fop.traits.TraitColorTestCase; -import org.apache.fop.util.ASCII85InputStreamTestCase; -import org.apache.fop.util.ASCII85OutputStreamTestCase; import org.apache.fop.util.PDFNumberTestCase; import junit.framework.Test; @@ -40,8 +38,6 @@ public class UtilityCodeTestSuite { TestSuite suite = new TestSuite( "Test suite for FOP's utility classes"); //$JUnit-BEGIN$ - suite.addTest(new TestSuite(ASCII85OutputStreamTestCase.class)); - suite.addTest(new TestSuite(ASCII85InputStreamTestCase.class)); suite.addTest(new TestSuite(PDFNumberTestCase.class)); suite.addTest(new TestSuite(TraitColorTestCase.class)); suite.addTest(new TestSuite(BorderPropsTestCase.class)); diff --git a/test/java/org/apache/fop/util/ASCII85InputStreamTestCase.java b/test/java/org/apache/fop/util/ASCII85InputStreamTestCase.java deleted file mode 100644 index 04033e913..000000000 --- a/test/java/org/apache/fop/util/ASCII85InputStreamTestCase.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.fop.pdf.PDFText; - -import junit.framework.TestCase; - -/** - * Test case for ASCII85InputStream. - *

    - * ATTENTION: Some of the tests here depend on the correct behaviour of - * ASCII85OutputStream. If something fails here make sure - * ASCII85OutputStreamTestCase runs! - */ -public class ASCII85InputStreamTestCase extends TestCase { - - private static final boolean DEBUG = false; - - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public ASCII85InputStreamTestCase(String name) { - super(name); - } - - private byte[] decode(String text) throws Exception { - byte[] ascii85 = text.getBytes("US-ASCII"); - InputStream in = new ByteArrayInputStream(ascii85); - InputStream decoder = new ASCII85InputStream(in); - return IOUtils.toByteArray(decoder); - } - - private byte[] getChunk(int count) { - byte[] buf = new byte[count]; - System.arraycopy(ASCII85OutputStreamTestCase.DATA, 0, buf, 0, buf.length); - return buf; - } - - private String encode(byte[] data, int len) throws Exception { - ByteArrayOutputStream baout = new ByteArrayOutputStream(); - java.io.OutputStream out = new ASCII85OutputStream(baout); - out.write(data, 0, len); - out.close(); - return new String(baout.toByteArray(), "US-ASCII"); - } - - - private void innerTestDecode(byte[] data) throws Exception { - String encoded = encode(data, data.length); - if (DEBUG) { - if (data[0] == 0) { - System.out.println("self-encode: " + data.length + " chunk 000102030405..."); - } else { - System.out.println("self-encode: " + new String(data, "US-ASCII") - + " " + PDFText.toHex(data)); - } - System.out.println(" ---> " + encoded); - } - byte[] decoded = decode(encoded); - if (DEBUG) { - if (data[0] == 0) { - System.out.println("decoded: " + data.length + " chunk 000102030405..."); - } else { - System.out.println("decoded: " + new String(decoded, "US-ASCII") - + " " + PDFText.toHex(decoded)); - } - } - assertEquals(PDFText.toHex(data), PDFText.toHex(decoded)); - } - - /** - * Tests the output of ASCII85. - * @throws Exception if an error occurs - */ - public void testDecode() throws Exception { - byte[] buf; - innerTestDecode("1. Bodypart".getBytes("US-ASCII")); - if (DEBUG) { - System.out.println("==========================================="); - } - - innerTestDecode(getChunk(1)); - innerTestDecode(getChunk(2)); - innerTestDecode(getChunk(3)); - innerTestDecode(getChunk(4)); - innerTestDecode(getChunk(5)); - if (DEBUG) { - System.out.println("==========================================="); - } - - innerTestDecode(getChunk(10)); - innerTestDecode(getChunk(62)); - innerTestDecode(getChunk(63)); - innerTestDecode(getChunk(64)); - innerTestDecode(getChunk(65)); - - if (DEBUG) { - System.out.println("==========================================="); - } - String sz; - sz = PDFText.toHex(decode("zz~>")); - assertEquals(PDFText.toHex(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}), sz); - sz = PDFText.toHex(decode("z\t \0z\n~>")); - assertEquals(PDFText.toHex(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}), sz); - if (DEBUG) { - System.out.println("==========================================="); - } - try { - decode("vz~>"); - fail("Illegal character should be detected"); - } catch (IOException ioe) { - //expected - } - /* DISABLED because of try/catch in InputStream.read(byte[], int, int). - * Only the exception happening on the first byte in a block is being - * reported. BUG in JDK??? - * - try { - decode("zv~>"); - fail("Illegal character should be detected"); - } catch (IOException ioe) { - //expected - }*/ - } - - private byte[] getFullASCIIRange() { - java.io.ByteArrayOutputStream baout = new java.io.ByteArrayOutputStream(256); - for (int i = 254; i < 256; i++) { - baout.write(i); - } - return baout.toByteArray(); - } - - /** - * Tests the full 8-bit ASCII range. - * @throws Exception if an error occurs - */ - public void testFullASCIIRange() throws Exception { - innerTestDecode(getFullASCIIRange()); - } - -} diff --git a/test/java/org/apache/fop/util/ASCII85OutputStreamTestCase.java b/test/java/org/apache/fop/util/ASCII85OutputStreamTestCase.java deleted file mode 100644 index 3ef1bf340..000000000 --- a/test/java/org/apache/fop/util/ASCII85OutputStreamTestCase.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.OutputStream; - -import org.apache.commons.io.output.ByteArrayOutputStream; - -import junit.framework.TestCase; - -/** - * Test case for ASCII85OutputStream - * - * @author Jeremias Maerki - */ -public class ASCII85OutputStreamTestCase extends TestCase { - - /** Test data */ - public static final byte[] DATA = new byte[100]; - - static { - //Fill in some data - for (int i = 0; i < 100; i++) { - DATA[i] = (byte)i; - } - } - - /** - * @see junit.framework.TestCase#TestCase(String) - */ - public ASCII85OutputStreamTestCase(String name) { - super(name); - } - - private String encode(int count) throws Exception { - return encode(DATA, count); - } - - private String encode(byte[] data, int len) throws Exception { - ByteArrayOutputStream baout = new ByteArrayOutputStream(); - OutputStream out = new ASCII85OutputStream(baout); - out.write(data, 0, len); - out.close(); - return new String(baout.toByteArray(), "US-ASCII"); - } - - /** - * Tests the output of ASCII85. - * @throws Exception if an error occurs - */ - public void testOutput() throws Exception { - String sz = encode(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}, 8); - assertEquals("zz~>", sz); - - String s3 = encode(3); - //System.out.println(">>>" + s3 + "<<<"); - assertEquals("!!*-~>", s3); - - String s10 = encode(10); - //System.out.println(">>>" + s10 + "<<<"); - assertEquals("!!*-'\"9eu7#RL~>", s10); - - String s62 = encode(62); - //System.out.println(">>>" + s62 + "<<<"); - assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," - + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?W~>", s62); - - String s63 = encode(63); - //System.out.println(">>>" + s63 + "<<<"); - assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," - + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Yk\n~>", s63); - - String s64 = encode(64); - //System.out.println(">>>" + s64 + "<<<"); - assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," - + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm\n~>", s64); - - String s65 = encode(65); - //System.out.println(">>>" + s65 + "<<<"); - assertEquals("!!*-'\"9eu7#RLhG$k3[W&.oNg'GVB\"(`=52*$$(B+<_pR," - + "UFcb-n-Vr/1iJ-0JP==1c70M3&s#]4?Ykm\n5Q~>", s65); - - } - -} -- 2.39.5