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-ffa450edef68tags/fop-0_92-beta
@@ -75,6 +75,7 @@ list of possible build targets. | |||
<fileset dir="${basedir}" id="dist.bin.lib"> | |||
<patternset id="dist.lib"> | |||
<include name="lib/avalon-framework*"/> | |||
<include name="lib/xmlgraphics-commons*"/> | |||
<include name="lib/batik*"/> | |||
<include name="lib/commons-io*"/> | |||
<include name="lib/commons-logging*"/> | |||
@@ -581,7 +582,7 @@ list of possible build targets. | |||
<include name="commons-io*.jar"/> | |||
<include name="avalon-framework*.jar"/> | |||
<include name="commons-logging*.jar"/> | |||
<include name="xmlgraphics*.jar"/> | |||
<include name="xmlgraphics-commons*.jar"/> | |||
</fileset> | |||
<target name="uptodate-transcoder-pkg" depends="compile-java"> | |||
@@ -626,6 +627,11 @@ list of possible build targets. | |||
<include name="org/apache/commons/io/output/ProxyOutputStream.class"/> | |||
<include name="org/apache/commons/io/output/ByteArrayOutputStream.class"/> | |||
<include name="org/apache/commons/io/output/CountingOutputStream.class"/> | |||
<!-- TODO Remove the following lines once Batik switches over to using XML Graphics Commons --> | |||
<include name="org/apache/xmlgraphics/java2d/**"/> | |||
<include name="org/apache/xmlgraphics/ps/**"/> | |||
<include name="org/apache/xmlgraphics/fonts/**"/> | |||
<include name="org/apache/xmlgraphics/util/io/**"/> | |||
</patternset> | |||
<fileset refid="transcoder-lib-files"/> | |||
</unjar> |
@@ -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 |
@@ -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. |
@@ -0,0 +1,2 @@ | |||
This product includes software developed by | |||
The Apache Software Foundation (http://www.apache.org/). |
@@ -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); | |||
} |
@@ -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(); |
@@ -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); |
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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. |
@@ -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. |
@@ -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. | |||
* <p> |
@@ -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); | |||
} |
@@ -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); | |||
} |
@@ -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) { |
@@ -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; |
@@ -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; |
@@ -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 <tt>PSGraphics2D</tt> that | |||
* is used to create a full document around the PostScript rendering from | |||
* <tt>PSGraphics2D</tt>. | |||
* | |||
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> | |||
* @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); | |||
} | |||
} | |||
@@ -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 <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> | |||
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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; |
@@ -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 <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a> | |||
* @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"; | |||
} |
@@ -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 <tt>AbstractPSDocumentGraphics2D</tt> 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); | |||
} | |||
} |
@@ -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 <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> | |||
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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 <tt>PSGraphics2D</tt> that | |||
* is used to create a full document around the PostScript rendering from | |||
* <tt>PSGraphics2D</tt>. | |||
* | |||
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> | |||
* @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 <code>Graphics</code> object that is | |||
* a copy of this <code>Graphics</code> object. | |||
* @return a new graphics context that is a copy of | |||
* this graphics context. | |||
*/ | |||
public Graphics create() { | |||
return new PSDocumentGraphics2D(this); | |||
} | |||
} | |||
@@ -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"); | |||
} | |||
} |
@@ -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 <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a> | |||
* @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 { | |||
} | |||
} |
@@ -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); |
@@ -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 <first filter> filter def"); | |||
// gen.write("/Data RawData <second filter> <third filter> [...] 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"); | |||
} | |||
} |
@@ -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 <a href="mailto:fop-dev@xmlgraphics.apache.org">Apache FOP Development Team</a> | |||
* @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"); | |||
// <font> <size> 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); | |||
} | |||
} |
@@ -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; | |||
/** |
@@ -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 <resource> 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(); | |||
} | |||
} |
@@ -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); |
@@ -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 <a href="mailto:fop-dev@xml.apache.org">Apache XML FOP Development Team</a> | |||
* @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); | |||
} | |||
} | |||
} |
@@ -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); |
@@ -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 <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> | |||
* @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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); | |||
} |
@@ -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 <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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; | |||
*/ | |||
} | |||
@@ -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. | |||
* <p> | |||
* 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. | |||
* <p> | |||
* 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; | |||
} | |||
} | |||
} | |||
@@ -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(); | |||
} | |||
} | |||
@@ -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 <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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(); | |||
} | |||
} | |||
@@ -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); | |||
} |
@@ -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 <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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; | |||
} |
@@ -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 <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
* @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(); | |||
} | |||
} | |||
} | |||
@@ -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 <a href="mailto:smwolke@geistig.com">Stephen Wolke</a> | |||
* @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(); | |||
} | |||
} | |||
@@ -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(); | |||
} | |||
} |
@@ -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. | |||
* <p> | |||
* 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; | |||
} | |||
} |
@@ -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)); |
@@ -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. | |||
* <p> | |||
* 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()); | |||
} | |||
} |
@@ -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 <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> | |||
*/ | |||
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); | |||
} | |||
} |