diff options
Diffstat (limited to 'src')
41 files changed, 401 insertions, 4489 deletions
diff --git a/src/java/org/apache/fop/fo/ElementMappingRegistry.java b/src/java/org/apache/fop/fo/ElementMappingRegistry.java index 3636500e0..8ab5a3d98 100644 --- a/src/java/org/apache/fop/fo/ElementMappingRegistry.java +++ b/src/java/org/apache/fop/fo/ElementMappingRegistry.java @@ -19,17 +19,19 @@ package org.apache.fop.fo; import java.util.Iterator; -import java.util.List; import java.util.Map; +import org.w3c.dom.DOMImplementation; +import org.xml.sax.Locator; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.util.Service; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.fo.ElementMapping.Maker; -import org.apache.fop.util.Service; -import org.w3c.dom.DOMImplementation; -import org.xml.sax.Locator; /** * This class keeps track of all configured ElementMapping implementations which are responsible @@ -69,9 +71,9 @@ public class ElementMappingRegistry { Iterator providers = Service.providers(ElementMapping.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + ElementMapping mapping = (ElementMapping)providers.next(); try { - addElementMapping(str); + addElementMapping(mapping); } catch (IllegalArgumentException e) { log.warn("Error while adding element mapping", e); } diff --git a/src/java/org/apache/fop/image/PNGImage.java b/src/java/org/apache/fop/image/PNGImage.java index 6cf50d47c..43cfbe97f 100644 --- a/src/java/org/apache/fop/image/PNGImage.java +++ b/src/java/org/apache/fop/image/PNGImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,13 @@ package org.apache.fop.image; -import java.awt.color.ColorSpace; -import java.awt.color.ICC_Profile; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.PNGRed; -import org.apache.batik.ext.awt.image.codec.PNGDecodeParam; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.codec.png.PNGRed; +import org.apache.xmlgraphics.image.codec.png.PNGDecodeParam; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.rendered.CachableRed; import org.apache.commons.io.IOUtils; -import org.apache.fop.util.CMYKColorSpace; /** * FopImage object using PNG @@ -36,7 +32,7 @@ import org.apache.fop.util.CMYKColorSpace; * @see AbstractFopImage * @see FopImage */ -public class PNGImage extends BatikImage { +public class PNGImage extends XmlGraphicsCommonsImage { /** * Constructs a new PNGImage instance. @@ -48,7 +44,8 @@ public class PNGImage extends BatikImage { } /** - * @see org.apache.fop.image.BatikImage#decodeImage(org.apache.batik.ext.awt.image.codec.SeekableStream) + * @see org.apache.fop.image.XmlGraphicsCommonsImage#decodeImage( + * org.apache.xmlgraphics.image.codec.util.SeekableStream) */ protected CachableRed decodeImage(SeekableStream stream) throws IOException { PNGDecodeParam param = new PNGDecodeParam(); diff --git a/src/java/org/apache/fop/image/TIFFImage.java b/src/java/org/apache/fop/image/TIFFImage.java index 7aa327c99..23337d01e 100644 --- a/src/java/org/apache/fop/image/TIFFImage.java +++ b/src/java/org/apache/fop/image/TIFFImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +21,17 @@ package org.apache.fop.image; import java.awt.color.ColorSpace; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFDirectory; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFField; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory; +import org.apache.xmlgraphics.image.codec.tiff.TIFFField; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; +import org.apache.xmlgraphics.image.rendered.CachableRed; import org.apache.commons.io.IOUtils; /** * TIFF implementation using the Batik codecs. */ -public class TIFFImage extends BatikImage { +public class TIFFImage extends XmlGraphicsCommonsImage { private int compression = 0; private int stripCount = 0; @@ -62,10 +62,13 @@ public class TIFFImage extends BatikImage { return stripCount; } - /** @see org.apache.fop.image.BatikImage */ + /** + * @see org.apache.fop.image.XmlGraphicsCommonsImage#decodeImage( + * org.apache.xmlgraphics.image.codec.util.SeekableStream) + */ protected CachableRed decodeImage(SeekableStream stream) throws IOException { - org.apache.batik.ext.awt.image.codec.tiff.TIFFImage img - = new org.apache.batik.ext.awt.image.codec.tiff.TIFFImage + org.apache.xmlgraphics.image.codec.tiff.TIFFImage img + = new org.apache.xmlgraphics.image.codec.tiff.TIFFImage (stream, null, 0); TIFFDirectory dir = (TIFFDirectory)img.getProperty("tiff_directory"); TIFFField fld = dir.getField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT); diff --git a/src/java/org/apache/fop/image/BatikImage.java b/src/java/org/apache/fop/image/XmlGraphicsCommonsImage.java index 1f6d7405b..ee079aad5 100644 --- a/src/java/org/apache/fop/image/BatikImage.java +++ b/src/java/org/apache/fop/image/XmlGraphicsCommonsImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2005 The Apache Software Foundation + * Copyright 2004-2006 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,24 +22,25 @@ import java.awt.Color; import java.awt.Transparency; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; +import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.io.IOException; -import org.apache.batik.ext.awt.image.codec.SeekableStream; -import org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream; -import org.apache.batik.ext.awt.image.codec.FileCacheSeekableStream; -import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed; -import org.apache.batik.ext.awt.image.rendered.CachableRed; +import org.apache.xmlgraphics.image.GraphicsUtil; +import org.apache.xmlgraphics.image.codec.util.SeekableStream; +import org.apache.xmlgraphics.image.codec.util.MemoryCacheSeekableStream; +import org.apache.xmlgraphics.image.codec.util.FileCacheSeekableStream; +import org.apache.xmlgraphics.image.rendered.CachableRed; + import org.apache.commons.io.IOUtils; /** - * FopImage object using TIFF - * @author Eric SCHAEFFER + * Abstract FopImage implementation which uses the internal codecs from XML Graphics Commons. * @see AbstractFopImage * @see FopImage */ -public abstract class BatikImage extends AbstractFopImage { +public abstract class XmlGraphicsCommonsImage extends AbstractFopImage { private byte[] softMask = null; @@ -57,7 +58,7 @@ public abstract class BatikImage extends AbstractFopImage { * Constructs a new BatikImage instance. * @param imgReader basic metadata for the image */ - public BatikImage(FopImage.ImageInfo imgReader) { + public XmlGraphicsCommonsImage(FopImage.ImageInfo imgReader) { super(imgReader); } @@ -105,7 +106,7 @@ public abstract class BatikImage extends AbstractFopImage { } } } else { - cr = new Any2sRGBRed(cr); + cr = GraphicsUtil.convertTosRGB(cr); } // Get our current ColorModel @@ -187,32 +188,7 @@ public abstract class BatikImage extends AbstractFopImage { this.bitmaps = new byte[this.width * this.height * 3]; - WritableRaster wr = (WritableRaster)cr.getData(); - BufferedImage bi = new BufferedImage - (cm, wr.createWritableTranslatedChild(0, 0), - cm.isAlphaPremultiplied(), null); - int [] tmpMap = new int[this.width]; - int idx = 0; - int sfIdx = 0; - for (int y = 0; y < this.height; y++) { - tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width); - if (softMask != null) { - for (int x = 0; x < this.width; x++) { - int pix = tmpMap[x]; - this.softMask[sfIdx++] = (byte)(pix >>> 24); - this.bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF); - this.bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF); - this.bitmaps[idx++] = (byte)((pix) & 0xFF); - } - } else { - for (int x = 0; x < this.width; x++) { - int pix = tmpMap[x]; - this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF); - this.bitmaps[idx++] = (byte)((pix >> 8) & 0xFF); - this.bitmaps[idx++] = (byte)((pix) & 0xFF); - } - } - } + constructBitmaps(cr, this.bitmaps, this.softMask); } catch (Exception ex) { log.error("Error while loading image (Batik): " + ex.getMessage(), ex); } finally { @@ -225,4 +201,37 @@ public abstract class BatikImage extends AbstractFopImage { } } } -}; + + private static void constructBitmaps(RenderedImage red, byte[] bitmaps, byte[] softMask) { + WritableRaster wr = (WritableRaster)red.getData(); + ColorModel cm = red.getColorModel(); + BufferedImage bi = new BufferedImage + (cm, wr.createWritableTranslatedChild(0, 0), + cm.isAlphaPremultiplied(), null); + int width = red.getWidth(); + int height = red.getHeight(); + int [] tmpMap = new int[width]; + int idx = 0; + int sfIdx = 0; + for (int y = 0; y < height; y++) { + tmpMap = bi.getRGB(0, y, width, 1, tmpMap, 0, width); + if (softMask != null) { + for (int x = 0; x < width; x++) { + int pix = tmpMap[x]; + softMask[sfIdx++] = (byte)(pix >>> 24); + bitmaps[idx++] = (byte)((pix >>> 16) & 0xFF); + bitmaps[idx++] = (byte)((pix >>> 8) & 0xFF); + bitmaps[idx++] = (byte)((pix) & 0xFF); + } + } else { + for (int x = 0; x < width; x++) { + int pix = tmpMap[x]; + bitmaps[idx++] = (byte)((pix >> 16) & 0xFF); + bitmaps[idx++] = (byte)((pix >> 8) & 0xFF); + bitmaps[idx++] = (byte)((pix) & 0xFF); + } + } + } + } + +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/pdf/ASCII85Filter.java b/src/java/org/apache/fop/pdf/ASCII85Filter.java index 689feb4a4..debb278fb 100644 --- a/src/java/org/apache/fop/pdf/ASCII85Filter.java +++ b/src/java/org/apache/fop/pdf/ASCII85Filter.java @@ -21,7 +21,7 @@ package org.apache.fop.pdf; import java.io.OutputStream; import java.io.IOException; -import org.apache.fop.util.ASCII85OutputStream; +import org.apache.xmlgraphics.util.io.ASCII85OutputStream; /** * PDF Filter for ASCII85. diff --git a/src/java/org/apache/fop/pdf/ASCIIHexFilter.java b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java index 9da799a19..72153397d 100644 --- a/src/java/org/apache/fop/pdf/ASCIIHexFilter.java +++ b/src/java/org/apache/fop/pdf/ASCIIHexFilter.java @@ -21,7 +21,7 @@ package org.apache.fop.pdf; import java.io.OutputStream; import java.io.IOException; -import org.apache.fop.util.ASCIIHexOutputStream; +import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream; /** * ASCII Hex filter for PDF streams. diff --git a/src/java/org/apache/fop/pdf/FlateFilter.java b/src/java/org/apache/fop/pdf/FlateFilter.java index f9bf5d61a..e9e2d4327 100644 --- a/src/java/org/apache/fop/pdf/FlateFilter.java +++ b/src/java/org/apache/fop/pdf/FlateFilter.java @@ -18,11 +18,11 @@ package org.apache.fop.pdf; -import org.apache.fop.util.FlateEncodeOutputStream; - import java.io.OutputStream; import java.io.IOException; +import org.apache.xmlgraphics.util.io.FlateEncodeOutputStream; + /** * A filter to deflate a stream. * <p> diff --git a/src/java/org/apache/fop/render/RendererFactory.java b/src/java/org/apache/fop/render/RendererFactory.java index 4108043bf..f2c052317 100644 --- a/src/java/org/apache/fop/render/RendererFactory.java +++ b/src/java/org/apache/fop/render/RendererFactory.java @@ -24,19 +24,18 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -//Avalon import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.container.ContainerUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -//FOP +import org.apache.xmlgraphics.util.Service; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.AreaTreeHandler; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.util.Service; /** * Factory for FOEventHandlers and Renderers. @@ -268,12 +267,13 @@ public class RendererFactory { = Service.providers(Renderer.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + AbstractRendererMaker maker = (AbstractRendererMaker)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding maker for Renderer: " + str); + log.debug("Dynamically adding maker for Renderer: " + + maker.getClass().getName()); } - addRendererMaker(str); + addRendererMaker(maker); } catch (IllegalArgumentException e) { log.error("Error while adding maker for Renderer", e); } @@ -292,12 +292,13 @@ public class RendererFactory { = Service.providers(FOEventHandler.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + AbstractFOEventHandlerMaker maker = (AbstractFOEventHandlerMaker)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding maker for FOEventHandler: " + str); + log.debug("Dynamically adding maker for FOEventHandler: " + + maker.getClass().getName()); } - addFOEventHandlerMaker(str); + addFOEventHandlerMaker(maker); } catch (IllegalArgumentException e) { log.error("Error while adding maker for FOEventHandler", e); } diff --git a/src/java/org/apache/fop/render/XMLHandlerRegistry.java b/src/java/org/apache/fop/render/XMLHandlerRegistry.java index 1603f74ec..c972f0322 100644 --- a/src/java/org/apache/fop/render/XMLHandlerRegistry.java +++ b/src/java/org/apache/fop/render/XMLHandlerRegistry.java @@ -24,7 +24,8 @@ import java.util.Map; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.util.Service;
+
+import org.apache.xmlgraphics.util.Service;
/**
* This class holds references to various XML handlers used by FOP. It also
@@ -148,12 +149,12 @@ public class XMLHandlerRegistry { Iterator providers = Service.providers(XMLHandler.class);
if (providers != null) {
while (providers.hasNext()) {
- String str = (String)providers.next();
+ XMLHandler handler = (XMLHandler)providers.next();
try {
if (log.isDebugEnabled()) {
- log.debug("Dynamically adding XMLHandler: " + str);
+ log.debug("Dynamically adding XMLHandler: " + handler.getClass().getName());
}
- addXMLHandler(str);
+ addXMLHandler(handler);
} catch (IllegalArgumentException e) {
log.error("Error while adding XMLHandler", e);
}
diff --git a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java index f6ed458c5..e89275484 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/PNGRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 The Apache Software Foundation. + * Copyright 2005-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import org.apache.batik.ext.awt.image.codec.PNGEncodeParam; -import org.apache.batik.ext.awt.image.codec.PNGImageEncoder; +import org.apache.xmlgraphics.image.writer.ImageWriter; +import org.apache.xmlgraphics.image.writer.ImageWriterParams; +import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; + import org.apache.commons.io.IOUtils; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; import org.apache.fop.area.PageViewport; @@ -50,9 +53,6 @@ public class PNGRenderer extends Java2DRenderer { /** The output directory where images are to be written */ private File outputDir; - /** The PNGEncodeParam for the image */ - private PNGEncodeParam renderParams; - /** The OutputStream for the first Image */ private OutputStream firstOutputStream; @@ -115,17 +115,13 @@ public class PNGRenderer extends Java2DRenderer { // Encode this image log.debug("Encoding page " + (i + 1)); - renderParams = PNGEncodeParam.getDefaultEncodeParam(image); - - // Set resolution - float pixSzMM = userAgent.getTargetPixelUnitToMillimeter(); - // num Pixs in 1 Meter - int numPix = (int)((1000 / pixSzMM) + 0.5); - renderParams.setPhysicalDimension(numPix, numPix, 1); // 1 means 'pix/meter' + ImageWriterParams params = new ImageWriterParams(); + params.setResolution(Math.round(userAgent.getTargetResolution())); // Encode PNG image - PNGImageEncoder encoder = new PNGImageEncoder(os, renderParams); - encoder.encode(image); + ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor(getMimeType()); + log.debug("Writing image using " + writer.getClass().getName()); + writer.writeImage(image, os, params); } finally { //Only close self-created OutputStreams if (os != firstOutputStream) { diff --git a/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java b/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java index 3f7ed34ab..cfef97430 100644 --- a/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java +++ b/src/java/org/apache/fop/render/bitmap/PNGRenderer_onthefly.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 The Apache Software Foundation. + * Copyright 2005-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import org.apache.batik.ext.awt.image.codec.PNGEncodeParam; -import org.apache.batik.ext.awt.image.codec.PNGImageEncoder; +import org.apache.xmlgraphics.image.codec.png.PNGEncodeParam; +import org.apache.xmlgraphics.image.codec.png.PNGImageEncoder; + import org.apache.commons.io.IOUtils; + import org.apache.fop.apps.FOPException; import org.apache.fop.area.PageViewport; import org.apache.fop.render.java2d.Java2DRenderer; diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java index 14e70d959..5379e6998 100644 --- a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java +++ b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,12 +33,12 @@ import java.util.Iterator; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.batik.ext.awt.image.GraphicsUtil; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFEncodeParam; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFField; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageDecoder; -import org.apache.batik.ext.awt.image.codec.tiff.TIFFImageEncoder; -import org.apache.batik.ext.awt.image.rendered.FormatRed; +import org.apache.xmlgraphics.image.GraphicsUtil; +import org.apache.xmlgraphics.image.codec.tiff.TIFFEncodeParam; +import org.apache.xmlgraphics.image.codec.tiff.TIFFField; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImageEncoder; +import org.apache.xmlgraphics.image.rendered.FormatRed; import org.apache.commons.logging.Log; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.MimeConstants; diff --git a/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java deleted file mode 100644 index 33c366a4d..000000000 --- a/src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.awt.Color; -import java.awt.Shape; -import java.awt.geom.AffineTransform; -import java.io.OutputStream; -import java.io.IOException; - -//FOP -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontSetup; - -/** - * This class is a wrapper for the <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); - } - - -} - diff --git a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java index 7ce111f33..bf960185d 100644 --- a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java @@ -24,7 +24,6 @@ import java.awt.Color; import java.io.IOException; import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.container.ContainerUtil; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.UnitProcessor; import org.apache.batik.transcoder.TranscoderException; @@ -32,7 +31,11 @@ import org.apache.batik.transcoder.TranscoderOutput; import org.apache.batik.transcoder.image.ImageTranscoder; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontSetup; import org.apache.fop.svg.AbstractFOPTranscoder; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.TextHandler; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGLength; @@ -62,7 +65,6 @@ import org.w3c.dom.svg.SVGLength; * millimeter conversion factor. * * @author <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; diff --git a/src/java/org/apache/fop/render/ps/DSCConstants.java b/src/java/org/apache/fop/render/ps/DSCConstants.java deleted file mode 100644 index f87b744db..000000000 --- a/src/java/org/apache/fop/render/ps/DSCConstants.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -/** - * This class defines constants with Strings for the DSC specification. - * - * @author <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"; - -} diff --git a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java deleted file mode 100644 index 461cfcadd..000000000 --- a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2003-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.io.IOException; - -import org.apache.fop.Version; - -/** - * This class is a wrapper for the <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); - } - -} diff --git a/src/java/org/apache/fop/render/ps/EPSTranscoder.java b/src/java/org/apache/fop/render/ps/EPSTranscoder.java index 37f4c8c78..8ca7c9b5b 100644 --- a/src/java/org/apache/fop/render/ps/EPSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/EPSTranscoder.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 The Apache Software Foundation. + * Copyright 1999-2004,2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ package org.apache.fop.render.ps; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D; + /** * This class enables to transcode an input to a EPS document. * @@ -43,7 +46,6 @@ package org.apache.fop.render.ps; * millimeter conversion factor. * * @author <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); } diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java new file mode 100644 index 000000000..2578b4c78 --- /dev/null +++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java @@ -0,0 +1,190 @@ +/* + * Copyright 1999-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.ps; + +import java.awt.Shape; +import java.awt.geom.AffineTransform; +import java.io.IOException; + +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.fonts.FontSetup; +import org.apache.fop.fonts.FontTriplet; + +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.java2d.ps.TextHandler; +import org.apache.xmlgraphics.ps.PSGenerator; + +/** + * Specialized TextHandler implementation that the PSGraphics2D class delegates to to paint text + * using PostScript text operations. + */ +public class NativeTextHandler implements TextHandler { + + private PSGraphics2D g2d; + + /** FontInfo containing all available fonts */ + protected FontInfo fontInfo; + + /** Currently valid Font */ + protected Font font; + + /** Overriding FontState */ + protected Font overrideFont = null; + + /** the current (internal) font name */ + protected String currentFontName; + + /** the current font size in millipoints */ + protected int currentFontSize; + + /** + * Main constructor. + * @param g2d the PSGraphics2D instance this instances is used by + * @param fontInfo the FontInfo object with all available fonts + */ + public NativeTextHandler(PSGraphics2D g2d, FontInfo fontInfo) { + this.g2d = g2d; + if (fontInfo != null) { + this.fontInfo = fontInfo; + } else { + setupFontInfo(); + } + } + + private void setupFontInfo() { + //Sets up a FontInfo with default fonts + fontInfo = new FontInfo(); + FontSetup.setup(fontInfo, null, null); + } + + /** + * Return the font information associated with this object + * @return the FontInfo object + */ + public FontInfo getFontInfo() { + return fontInfo; + } + + private PSGenerator getPSGenerator() { + return this.g2d.getPSGenerator(); + } + + /** @see org.apache.xmlgraphics.java2d.ps.TextHandler#writeSetup() */ + public void writeSetup() throws IOException { + if (fontInfo != null) { + PSFontUtils.writeFontDict(getPSGenerator(), fontInfo); + } + } + + /** @see org.apache.xmlgraphics.java2d.ps.TextHandler#writePageSetup() */ + public void writePageSetup() throws IOException { + if (fontInfo != null) { + getPSGenerator().writeln("FOPFonts begin"); + } + } + + /** + * Draw a string to the PostScript document. The text is painted using + * text operations. + * @see org.apache.xmlgraphics.java2d.ps.TextHandler#drawString(java.lang.String, float, float) + */ + public void drawString(String s, float x, float y) throws IOException { + g2d.preparePainting(); + if (this.overrideFont == null) { + java.awt.Font awtFont = g2d.getFont(); + this.font = createFont(awtFont); + } else { + this.font = this.overrideFont; + this.overrideFont = null; + } + + //Color and Font state + g2d.establishColor(g2d.getColor()); + establishCurrentFont(); + + PSGenerator gen = getPSGenerator(); + gen.saveGraphicsState(); + + //Clip + Shape imclip = g2d.getClip(); + g2d.writeClip(imclip); + + //Prepare correct transformation + AffineTransform trans = g2d.getTransform(); + gen.concatMatrix(trans); + gen.writeln(gen.formatDouble(x) + " " + + gen.formatDouble(y) + " moveto "); + gen.writeln("1 -1 scale"); + + StringBuffer sb = new StringBuffer("("); + escapeText(s, sb); + sb.append(") t "); + + gen.writeln(sb.toString()); + + gen.restoreGraphicsState(); + } + + private void escapeText(final String text, StringBuffer target) { + final int l = text.length(); + for (int i = 0; i < l; i++) { + final char ch = text.charAt(i); + final char mch = this.font.mapChar(ch); + PSGenerator.escapeChar(mch, target); + } + } + + private Font createFont(java.awt.Font f) { + String fontFamily = f.getFamily(); + if (fontFamily.equals("sanserif")) { + fontFamily = "sans-serif"; + } + int fontSize = 1000 * f.getSize(); + String style = f.isItalic() ? "italic" : "normal"; + int weight = f.isBold() ? Font.BOLD : Font.NORMAL; + + FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight); + if (triplet == null) { + triplet = fontInfo.findAdjustWeight("sans-serif", style, weight); + } + return fontInfo.getFontInstance(triplet, fontSize); + } + + private void establishCurrentFont() throws IOException { + if ((currentFontName != this.font.getFontName()) + || (currentFontSize != this.font.getFontSize())) { + PSGenerator gen = getPSGenerator(); + gen.writeln(this.font.getFontName() + " " + + gen.formatDouble(font.getFontSize() / 1000f) + " F"); + currentFontName = this.font.getFontName(); + currentFontSize = this.font.getFontSize(); + } + } + + /** + * Sets the overriding font. + * @param override Overriding Font to set + */ + public void setOverrideFont(Font override) { + this.overrideFont = override; + } + + +} diff --git a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java deleted file mode 100644 index b2a1c07a0..000000000 --- a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.awt.Graphics; -import java.io.OutputStream; -import java.io.IOException; - -//FOP -import org.apache.fop.Version; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontSetup; - -/** - * This class is a wrapper for the <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); - } - -} - diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java index 3478a0751..f56e18bb9 100644 --- a/src/java/org/apache/fop/render/ps/PSFontUtils.java +++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java @@ -18,7 +18,6 @@ package org.apache.fop.render.ps; -import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -29,22 +28,20 @@ import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; -import org.apache.commons.io.EndianUtils; -import org.apache.commons.io.IOUtils; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontType; -import org.apache.fop.fonts.Glyphs; import org.apache.fop.fonts.LazyFont; import org.apache.fop.fonts.Typeface; -import org.apache.fop.util.ASCIIHexOutputStream; -import org.apache.fop.util.SubInputStream; +import org.apache.xmlgraphics.ps.DSCConstants; +import org.apache.xmlgraphics.ps.PSGenerator; +import org.apache.xmlgraphics.ps.PSResource; /** * Utility code for font handling in PostScript. */ -public class PSFontUtils { +public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { /** * Generates the PostScript code for the font dictionary. @@ -133,56 +130,6 @@ public class PSFontUtils { return fontResources; } - /** - * This method reads a Type 1 font from a stream and embeds it into a PostScript stream. - * Note: Only the IBM PC Format as described in section 3.3 of the Adobe Technical Note #5040 - * is supported. - * @param gen The PostScript generator - * @param in the InputStream from which to read the Type 1 font - * @throws IOException in case an I/O problem occurs - */ - private static void embedType1Font(PSGenerator gen, InputStream in) throws IOException { - boolean finished = false; - while (!finished) { - int segIndicator = in.read(); - if (segIndicator < 0) { - throw new IOException("Unexpected end-of-file while reading segment indicator"); - } else if (segIndicator != 128) { - throw new IOException("Expected ASCII 128, found: " + segIndicator); - } - int segType = in.read(); - if (segType < 0) { - throw new IOException("Unexpected end-of-file while reading segment type"); - } - int dataSegLen = 0; - switch (segType) { - case 1: //ASCII - dataSegLen = EndianUtils.readSwappedInteger(in); - - BufferedReader reader = new BufferedReader( - new java.io.InputStreamReader( - new SubInputStream(in, dataSegLen), "US-ASCII")); - String line; - while ((line = reader.readLine()) != null) { - gen.writeln(line); - } - break; - case 2: //binary - dataSegLen = EndianUtils.readSwappedInteger(in); - - SubInputStream sin = new SubInputStream(in, dataSegLen); - ASCIIHexOutputStream hexOut = new ASCIIHexOutputStream(gen.getOutputStream()); - IOUtils.copy(sin, hexOut); - gen.newLine(); - break; - case 3: //EOF - finished = true; - break; - default: throw new IOException("Unsupported segment type: " + segType); - } - } - } - private static InputStream getInputStreamOnFont(PSGenerator gen, CustomFont font) throws IOException { if (font.isEmbeddable()) { @@ -220,28 +167,4 @@ public class PSFontUtils { } } - private static void defineWinAnsiEncoding(PSGenerator gen) throws IOException { - gen.writeln("/WinAnsiEncoding ["); - for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) { - if (i > 0) { - if ((i % 5) == 0) { - gen.newLine(); - } else { - gen.write(" "); - } - } - final char ch = Glyphs.WINANSI_ENCODING[i]; - final String glyphname = Glyphs.charToGlyphName(ch); - if ("".equals(glyphname)) { - gen.write("/" + Glyphs.NOTDEF); - } else { - gen.write("/"); - gen.write(glyphname); - } - } - gen.newLine(); - gen.writeln("] def"); - } - - } diff --git a/src/java/org/apache/fop/render/ps/PSGenerator.java b/src/java/org/apache/fop/render/ps/PSGenerator.java deleted file mode 100644 index 14d5b18fa..000000000 --- a/src/java/org/apache/fop/render/ps/PSGenerator.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.awt.Color; -import java.awt.geom.AffineTransform; -import java.io.OutputStream; -import java.io.IOException; -import java.text.DateFormat; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Date; -import java.util.Iterator; -import java.util.Locale; -import java.util.Set; -import java.util.Stack; - -import javax.xml.transform.Source; - -/** - * This class is used to output PostScript code to an OutputStream. - * - * @author <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 { - } - - -} diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2D.java b/src/java/org/apache/fop/render/ps/PSGraphics2D.java deleted file mode 100644 index eb7b59e39..000000000 --- a/src/java/org/apache/fop/render/ps/PSGraphics2D.java +++ /dev/null @@ -1,1181 +0,0 @@ -/* - * Copyright 1999-2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -//Java -import java.text.AttributedCharacterIterator; -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Dimension; -/* java.awt.Font is not imported to avoid confusion with - org.apache.fop.fonts.Font */ -import java.awt.GradientPaint; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.TexturePaint; -import java.awt.color.ColorSpace; -import java.awt.color.ICC_Profile; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferInt; -import java.awt.image.ImageObserver; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; -import java.io.IOException; - -//Batik -import org.apache.batik.ext.awt.RenderingHintsKeyExt; -import org.apache.batik.ext.awt.g2d.AbstractGraphics2D; -import org.apache.batik.ext.awt.g2d.GraphicContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -//FOP -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.image.FopImage; - -/** - * This concrete implementation of <tt>AbstractGraphics2D</tt> is a - * simple help to programmers to get started with their own - * implementation of <tt>Graphics2D</tt>. - * <tt>DefaultGraphics2D</tt> implements all the abstract methods - * is <tt>AbstractGraphics2D</tt> and makes it easy to start - * implementing a <tt>Graphic2D</tt> piece-meal. - * - * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a> - * @version $Id$ - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D - */ -public class PSGraphics2D extends AbstractGraphics2D { - - private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform(); - - /** the logger for this class */ - protected Log log = LogFactory.getLog(PSTextPainter.class); - - /** the PostScript generator being created */ - protected PSGenerator gen; - - private boolean clippingDisabled = false; - - /** Currently valid FontState */ - protected Font font; - - /** Overriding FontState */ - protected Font overrideFont = null; - - /** the current (internal) font name */ - protected String currentFontName; - - /** the current font size in millipoints */ - protected int currentFontSize; - - /** - * the current colour for use in svg - */ - protected Color currentColour = new Color(0, 0, 0); - - /** FontInfo containing all available fonts */ - protected FontInfo fontInfo; - - /** - * Create a new Graphics2D that generates PostScript code. - * @param textAsShapes True if text should be rendered as graphics - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) - */ - public PSGraphics2D(boolean textAsShapes) { - super(textAsShapes); - } - - /** - * Create a new Graphics2D that generates PostScript code. - * @param textAsShapes True if text should be rendered as graphics - * @param gen PostScript generator to use for output - * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D#AbstractGraphics2D(boolean) - */ - public PSGraphics2D(boolean textAsShapes, PSGenerator gen) { - this(textAsShapes); - setPSGenerator(gen); - } - - /** - * Constructor for creating copies - * @param g parent PostScript Graphics2D - */ - public PSGraphics2D(PSGraphics2D g) { - super(g); - - setPSGenerator(g.gen); - this.clippingDisabled = g.clippingDisabled; - this.font = g.font; - this.overrideFont = g.overrideFont; - this.currentFontName = g.currentFontName; - this.currentFontSize = g.currentFontSize; - this.currentColour = g.currentColour; - this.fontInfo = g.fontInfo; - } - - /** - * Sets the PostScript generator - * @param gen the PostScript generator - */ - public void setPSGenerator(PSGenerator gen) { - this.gen = gen; - } - - /** - * Sets the GraphicContext - * @param c GraphicContext to use - */ - public void setGraphicContext(GraphicContext c) { - gc = c; - setPrivateHints(); - } - - private void setPrivateHints() { - setRenderingHint(RenderingHintsKeyExt.KEY_AVOID_TILE_PAINTING, - RenderingHintsKeyExt.VALUE_AVOID_TILE_PAINTING_ON); - } - - /** - * Creates a new <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 PSGraphics2D(this); - } - - /** - * Return the font information associated with this object - * @return the FontInfo object - */ - public FontInfo getFontInfo() { - return fontInfo; - } - - /** - * Central handler for IOExceptions for this class. - * @param ioe IOException to handle - */ - protected void handleIOException(IOException ioe) { - //TODO Surely, there's a better way to do this. - ioe.printStackTrace(); - } - - /** - * This method is used by AbstractPSDocumentGraphics2D to prepare a new page if - * necessary. - */ - protected void preparePainting() { - //nop, used by AbstractPSDocumentGraphics2D - } - - /** - * Draws as much of the specified image as is currently available. - * The image is drawn with its top-left corner at - * (<i>x</i>, <i>y</i>) in this graphics context's coordinate - * space. Transparent pixels in the image do not affect whatever - * pixels are already there. - * <p> - * This method returns immediately in all cases, even if the - * complete image has not yet been loaded, and it has not been dithered - * and converted for the current output device. - * <p> - * If the image has not yet been completely loaded, then - * <code>drawImage</code> returns <code>false</code>. As more of - * the image becomes available, the process that draws the image notifies - * the specified image observer. - * @param img the specified image to be drawn. - * @param x the <i>x</i> coordinate. - * @param y the <i>y</i> coordinate. - * @param observer object to be notified as more of - * the image is converted. - * @return True if the image has been fully drawn/loaded - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - public boolean drawImage(Image img, int x, int y, - ImageObserver observer) { - preparePainting(); - log.debug("drawImage: " + x + ", " + y + " " + img.getClass().getName()); - - final int width = img.getWidth(observer); - final int height = img.getHeight(observer); - if (width == -1 || height == -1) { - return false; - } - - Dimension size = new Dimension(width, height); - BufferedImage buf = buildBufferedImage(size); - - java.awt.Graphics2D g = buf.createGraphics(); - g.setComposite(AlphaComposite.SrcOver); - g.setBackground(new Color(1, 1, 1, 0)); - g.setPaint(new Color(1, 1, 1, 0)); - g.fillRect(0, 0, width, height); - g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); - - if (!g.drawImage(img, 0, 0, observer)) { - return false; - } - g.dispose(); - - final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3]; - //final byte[] mask = new byte[buf.getWidth() * buf.getHeight()]; - - Raster raster = buf.getData(); - DataBuffer bd = raster.getDataBuffer(); - - int count = 0; - //int maskpos = 0; - switch (bd.getDataType()) { - case DataBuffer.TYPE_INT: - int[][] idata = ((DataBufferInt)bd).getBankData(); - for (int i = 0; i < idata.length; i++) { - for (int j = 0; j < idata[i].length; j++) { - // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF); - if (((idata[i][j] >> 24) & 0xFF) != 255) { - result[count++] = (byte)0xFF; - result[count++] = (byte)0xFF; - result[count++] = (byte)0xFF; - } else { - result[count++] = (byte)((idata[i][j] >> 16) & 0xFF); - result[count++] = (byte)((idata[i][j] >> 8) & 0xFF); - result[count++] = (byte)((idata[i][j]) & 0xFF); - } - } - } - break; - default: - // error - break; - } - - try { - FopImage fopimg = new TempImage(width, height, result, null); - AffineTransform at = getTransform(); - gen.saveGraphicsState(); - gen.concatMatrix(at); - Shape imclip = getClip(); - writeClip(imclip); - PSImageUtils.renderBitmapImage(fopimg, - x, y, width, height, gen); - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - - return true; - } - - /** - * Creates a buffered image. - * @param size dimensions of the image to be created - * @return the buffered image - */ - public BufferedImage buildBufferedImage(Dimension size) { - return new BufferedImage(size.width, size.height, - BufferedImage.TYPE_INT_ARGB); - } - - - class TempImage implements FopImage { - private int height; - private int width; - private int bitsPerPixel; - private ColorSpace colorSpace; - private byte[] bitmaps; - private byte[] mask; - private Color transparentColor; - - TempImage(int width, int height, byte[] bitmaps, - byte[] mask) { - this.height = height; - this.width = width; - this.bitsPerPixel = 8; - this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); - this.bitmaps = bitmaps; - this.mask = mask; - } - - public String getMimeType() { - return "application/octet-stream"; - } - - public String getOriginalURI() { - return "temp-image:" + this.toString(); - } - - /** - * @see org.apache.fop.image.FopImage#load(int, org.apache.commons.logging.Log) - */ - public boolean load(int type) { - switch (type) { - case FopImage.DIMENSIONS: break; - case FopImage.BITMAP: break; - case FopImage.ORIGINAL_DATA: break; - default: throw new RuntimeException("Unknown load type: " + type); - } - return true; - } - - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } - - public ColorSpace getColorSpace() { - return this.colorSpace; - } - - public ICC_Profile getICCProfile() { - return null; - } - - public int getBitsPerPixel() { - return this.bitsPerPixel; - } - - // For transparent images - public boolean isTransparent() { - return getTransparentColor() != null; - } - - public Color getTransparentColor() { - return this.transparentColor; - } - - public boolean hasSoftMask() { - return this.mask != null; - } - - public byte[] getSoftMask() { - return this.mask; - } - - public boolean isInverted() { - return false; - } - - public byte[] getBitmaps() { - return this.bitmaps; - } - - // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() { - return getWidth() * getHeight() * 3; //Assumes RGB! - } - - // get compressed image bytes - // I don't know if we really need it, nor if it - // should be changed... - public byte[] getRessourceBytes() { - return null; - } - - public int getRessourceBytesSize() { - return 0; - } - - /** @see org.apache.fop.image.FopImage#getIntrinsicWidth() */ - public int getIntrinsicWidth() { - return (int)(getWidth() * 72 / getHorizontalResolution()); - } - - /** @see org.apache.fop.image.FopImage#getIntrinsicHeight() */ - public int getIntrinsicHeight() { - return (int)(getHeight() * 72 / getVerticalResolution()); - } - - /** @see org.apache.fop.image.FopImage#getHorizontalResolution() */ - public double getHorizontalResolution() { - return 72; - } - - /** @see org.apache.fop.image.FopImage#getVerticalResolution() */ - public double getVerticalResolution() { - return 72; - } - - } - - - /** - * Draws as much of the specified image as has already been scaled - * to fit inside the specified rectangle. - * <p> - * The image is drawn inside the specified rectangle of this - * graphics context's coordinate space, and is scaled if - * necessary. Transparent pixels do not affect whatever pixels - * are already there. - * <p> - * This method returns immediately in all cases, even if the - * entire image has not yet been scaled, dithered, and converted - * for the current output device. - * If the current output representation is not yet complete, then - * <code>drawImage</code> returns <code>false</code>. As more of - * the image becomes available, the process that draws the image notifies - * the image observer by calling its <code>imageUpdate</code> method. - * <p> - * A scaled version of an image will not necessarily be - * available immediately just because an unscaled version of the - * image has been constructed for this output device. Each size of - * the image may be cached separately and generated from the original - * data in a separate image production sequence. - * @param img the specified image to be drawn. - * @param x the <i>x</i> coordinate. - * @param y the <i>y</i> coordinate. - * @param width the width of the rectangle. - * @param height the height of the rectangle. - * @param observer object to be notified as more of - * the image is converted. - * @return True if the image has been fully loaded/drawn - * @see java.awt.Image - * @see java.awt.image.ImageObserver - * @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int) - */ - public boolean drawImage(Image img, int x, int y, int width, int height, - ImageObserver observer) { - preparePainting(); - log.warn("NYI: drawImage"); - return true; - } - - /** - * Disposes of this graphics context and releases - * any system resources that it is using. - * A <code>Graphics</code> object cannot be used after - * <code>dispose</code>has been called. - * <p> - * When a Java program runs, a large number of <code>Graphics</code> - * objects can be created within a short time frame. - * Although the finalization process of the garbage collector - * also disposes of the same system resources, it is preferable - * to manually free the associated resources by calling this - * method rather than to rely on a finalization process which - * may not run to completion for a long period of time. - * <p> - * Graphics objects which are provided as arguments to the - * <code>paint</code> and <code>update</code> methods - * of components are automatically released by the system when - * those methods return. For efficiency, programmers should - * call <code>dispose</code> when finished using - * a <code>Graphics</code> object only if it was created - * directly from a component or another <code>Graphics</code> object. - * @see java.awt.Graphics#finalize - * @see java.awt.Component#paint - * @see java.awt.Component#update - * @see java.awt.Component#getGraphics - * @see java.awt.Graphics#create - */ - public void dispose() { - this.gen = null; - this.font = null; - this.currentColour = null; - this.fontInfo = null; - } - - /** - * Processes a path iterator generating the nexessary painting operations. - * @param iter PathIterator to process - * @throws IOException In case of an I/O problem. - */ - public void processPathIterator(PathIterator iter) throws IOException { - double[] vals = new double[6]; - while (!iter.isDone()) { - int type = iter.currentSegment(vals); - switch (type) { - case PathIterator.SEG_CUBICTO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) + " " - + gen.formatDouble(vals[2]) + " " - + gen.formatDouble(vals[3]) + " " - + gen.formatDouble(vals[4]) + " " - + gen.formatDouble(vals[5]) - + " curveto"); - break; - case PathIterator.SEG_LINETO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) - + " lineto"); - break; - case PathIterator.SEG_MOVETO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) - + " M"); - break; - case PathIterator.SEG_QUADTO: - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) + " " - + gen.formatDouble(vals[2]) + " " - + gen.formatDouble(vals[3]) + " QUADTO "); - break; - case PathIterator.SEG_CLOSE: - gen.writeln("closepath"); - break; - default: - break; - } - iter.next(); - } - } - - /** - * Strokes the outline of a <code>Shape</code> using the settings of the - * current <code>Graphics2D</code> context. The rendering attributes - * applied include the <code>Clip</code>, <code>Transform</code>, - * <code>Paint</code>, <code>Composite</code> and - * <code>Stroke</code> attributes. - * @param s the <code>Shape</code> to be rendered - * @see #setStroke - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #transform - * @see #setTransform - * @see #clip - * @see #setClip - * @see #setComposite - */ - public void draw(Shape s) { - preparePainting(); - try { - gen.saveGraphicsState(); - - AffineTransform trans = getTransform(); - boolean newTransform = gen.getCurrentState().checkTransform(trans) - && !trans.isIdentity(); - - if (newTransform) { - gen.concatMatrix(trans); - } - Shape imclip = getClip(); - writeClip(imclip); - establishColor(getColor()); - - applyPaint(getPaint(), false); - applyStroke(getStroke()); - - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - doDrawing(false, true, false); - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - /** - * Establishes a clipping region - * @param s Shape defining the clipping region - */ - protected void writeClip(Shape s) { - if (s == null) { - return; - } - if (!this.clippingDisabled) { - preparePainting(); - try { - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - // clip area - gen.writeln("clip"); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - } - - /** - * Applies a new Paint object. - * @param paint Paint object to use - * @param fill True if to be applied for filling - */ - protected void applyPaint(Paint paint, boolean fill) { - preparePainting(); - if (paint instanceof GradientPaint) { - log.warn("NYI: Gradient paint"); - } else if (paint instanceof TexturePaint) { - log.warn("NYI: texture paint"); - } - } - - /** - * Applies a new Stroke object. - * @param stroke Stroke object to use - */ - protected void applyStroke(Stroke stroke) { - preparePainting(); - try { - if (stroke instanceof BasicStroke) { - BasicStroke bs = (BasicStroke)stroke; - - float[] da = bs.getDashArray(); - if (da != null) { - gen.write("["); - for (int count = 0; count < da.length; count++) { - gen.write("" + ((int)da[count])); - if (count < da.length - 1) { - gen.write(" "); - } - } - gen.write("] "); - float offset = bs.getDashPhase(); - gen.writeln(((int)offset) + " setdash"); - } - int ec = bs.getEndCap(); - switch (ec) { - case BasicStroke.CAP_BUTT: - gen.writeln("0 setlinecap"); - break; - case BasicStroke.CAP_ROUND: - gen.writeln("1 setlinecap"); - break; - case BasicStroke.CAP_SQUARE: - gen.writeln("2 setlinecap"); - break; - default: log.warn("Unsupported line cap: " + ec); - } - - int lj = bs.getLineJoin(); - switch (lj) { - case BasicStroke.JOIN_MITER: - gen.writeln("0 setlinejoin"); - break; - case BasicStroke.JOIN_ROUND: - gen.writeln("1 setlinejoin"); - break; - case BasicStroke.JOIN_BEVEL: - gen.writeln("2 setlinejoin"); - break; - default: log.warn("Unsupported line join: " + lj); - } - float lw = bs.getLineWidth(); - gen.writeln(gen.formatDouble(lw) + " setlinewidth"); - - float ml = bs.getMiterLimit(); - gen.writeln(gen.formatDouble(ml) + " setmiterlimit"); - } - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - /** - * Renders a {@link RenderedImage}, - * applying a transform from image - * space into user space before drawing. - * The transformation from user space into device space is done with - * the current <code>Transform</code> in the <code>Graphics2D</code>. - * The specified transformation is applied to the image before the - * transform attribute in the <code>Graphics2D</code> context is applied. - * The rendering attributes applied include the <code>Clip</code>, - * <code>Transform</code>, and <code>Composite</code> attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - * @param img the image to be rendered - * @param xform the transformation from image space into user space - * @see #transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - preparePainting(); - log.warn("NYI: drawRenderedImage"); - } - - /** - * Renders a - * {@link RenderableImage}, - * applying a transform from image space into user space before drawing. - * The transformation from user space into device space is done with - * the current <code>Transform</code> in the <code>Graphics2D</code>. - * The specified transformation is applied to the image before the - * transform attribute in the <code>Graphics2D</code> context is applied. - * The rendering attributes applied include the <code>Clip</code>, - * <code>Transform</code>, and <code>Composite</code> attributes. Note - * that no rendering is done if the specified transform is - * noninvertible. - * <p> - * Rendering hints set on the <code>Graphics2D</code> object might - * be used in rendering the <code>RenderableImage</code>. - * If explicit control is required over specific hints recognized by a - * specific <code>RenderableImage</code>, or if knowledge of which hints - * are used is required, then a <code>RenderedImage</code> should be - * obtained directly from the <code>RenderableImage</code> - * and rendered using - * {@link #drawRenderedImage(RenderedImage, AffineTransform) drawRenderedImage}. - * @param img the image to be rendered - * @param xform the transformation from image space into user space - * @see #transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - * @see #drawRenderedImage - */ - public void drawRenderableImage(RenderableImage img, - AffineTransform xform) { - preparePainting(); - log.warn("NYI: drawRenderableImage"); - } - - /** - * Establishes the given color in the PostScript interpreter. - * @param c the color to set - * @throws IOException In case of an I/O problem - */ - protected void establishColor(Color c) throws IOException { - StringBuffer p = new StringBuffer(); - float[] comps = c.getColorComponents(null); - - if (c.getColorSpace().getType() == ColorSpace.TYPE_RGB) { - // according to pdfspec 12.1 p.399 - // if the colors are the same then just use the g or G operator - boolean same = (comps[0] == comps[1] - && comps[0] == comps[2]); - // output RGB - if (same) { - p.append(gen.formatDouble(comps[0])); - } else { - for (int i = 0; i < c.getColorSpace().getNumComponents(); i++) { - if (i > 0) { - p.append(" "); - } - p.append(gen.formatDouble(comps[i])); - } - } - if (same) { - p.append(" setgray"); - } else { - p.append(" setrgbcolor"); - } - } else if (c.getColorSpace().getType() == ColorSpace.TYPE_CMYK) { - // colorspace is CMYK - for (int i = 0; i < c.getColorSpace().getNumComponents(); i++) { - if (i > 0) { - p.append(" "); - } - p.append(gen.formatDouble(comps[i])); - } - p.append(" setcmykcolor"); - } else { - // means we're in DeviceGray or Unknown. - // assume we're in DeviceGray, because otherwise we're screwed. - p.append(gen.formatDouble(comps[0])); - p.append(" setgray"); - } - gen.writeln(p.toString()); - } - - /** - * Renders the text specified by the specified <code>String</code>, - * using the current <code>Font</code> and <code>Paint</code> attributes - * in the <code>Graphics2D</code> context. - * The baseline of the first character is at position - * (<i>x</i>, <i>y</i>) in the User Space. - * The rendering attributes applied include the <code>Clip</code>, - * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and - * <code>Composite</code> attributes. For characters in script systems - * such as Hebrew and Arabic, the glyphs can be rendered from right to - * left, in which case the coordinate supplied is the location of the - * leftmost character on the baseline. - * @param s the <code>String</code> to be rendered - * @param x the x-coordinate where the <code>String</code> - * should be rendered - * @param y the y-coordinate where the <code>String</code> - * should be rendered - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see java.awt.Graphics#setFont - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - public void drawString(String s, float x, float y) { - if (this.textAsShapes) { - drawStringAsShapes(s, x, y); - } else { - drawStringAsText(s, x, y); - } - } - - /** - * Draw a string to the PostScript document. The text is painted as shapes. - * @param s the string to draw - * @param x the x position - * @param y the y position - */ - public void drawStringAsShapes(String s, float x, float y) { - java.awt.Font awtFont = super.getFont(); - FontRenderContext frc = super.getFontRenderContext(); - GlyphVector gv = awtFont.createGlyphVector(frc, s); - Shape glyphOutline = gv.getOutline(x, y); - fill(glyphOutline); - } - - /** - * Draw a string to the PostScript document. The text is painted using - * text operations. - * @param s the string to draw - * @param x the x position - * @param y the y position - */ - public void drawStringAsText(String s, float x, float y) { - preparePainting(); - log.trace("drawString('" + s + "', " + x + ", " + y + ")"); - try { - if (this.overrideFont == null) { - java.awt.Font awtFont = getFont(); - this.font = createFont(awtFont); - } else { - this.font = this.overrideFont; - this.overrideFont = null; - } - - //Color and Font state - establishColor(getColor()); - establishCurrentFont(); - - //Clip - Shape imclip = getClip(); - writeClip(imclip); - - gen.saveGraphicsState(); - - //Prepare correct transformation - AffineTransform trans = getTransform(); - gen.concatMatrix(trans); - gen.writeln(gen.formatDouble(x) + " " - + gen.formatDouble(y) + " moveto "); - gen.writeln("1 -1 scale"); - - StringBuffer sb = new StringBuffer("("); - escapeText(s, sb); - sb.append(") t "); - - gen.writeln(sb.toString()); - - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - private void escapeText(final String text, StringBuffer target) { - final int l = text.length(); - for (int i = 0; i < l; i++) { - final char ch = text.charAt(i); - final char mch = this.font.mapChar(ch); - PSGenerator.escapeChar(mch, target); - } - } - - private Font createFont(java.awt.Font f) { - String fontFamily = f.getFamily(); - if (fontFamily.equals("sanserif")) { - fontFamily = "sans-serif"; - } - int fontSize = 1000 * f.getSize(); - String style = f.isItalic() ? "italic" : "normal"; - int weight = f.isBold() ? Font.BOLD : Font.NORMAL; - - FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight); - if (triplet == null) { - triplet = fontInfo.findAdjustWeight("sans-serif", style, weight); - } - return fontInfo.getFontInstance(triplet, fontSize); - } - - private void establishCurrentFont() throws IOException { - if ((currentFontName != this.font.getFontName()) - || (currentFontSize != this.font.getFontSize())) { - gen.writeln(this.font.getFontName() + " " + this.font.getFontSize() + " F"); - currentFontName = this.font.getFontName(); - currentFontSize = this.font.getFontSize(); - } - } - - /** - * Renders the text of the specified iterator, using the - * <code>Graphics2D</code> context's current <code>Paint</code>. The - * iterator must specify a font - * for each character. The baseline of the - * first character is at position (<i>x</i>, <i>y</i>) in the - * User Space. - * The rendering attributes applied include the <code>Clip</code>, - * <code>Transform</code>, <code>Paint</code>, and - * <code>Composite</code> attributes. - * For characters in script systems such as Hebrew and Arabic, - * the glyphs can be rendered from right to left, in which case the - * coordinate supplied is the location of the leftmost character - * on the baseline. - * @param iterator the iterator whose text is to be rendered - * @param x the x-coordinate where the iterator's text is to be - * rendered - * @param y the y-coordinate where the iterator's text is to be - * rendered - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #setTransform - * @see #setComposite - * @see #setClip - */ - public void drawString(AttributedCharacterIterator iterator, float x, - float y) { - preparePainting(); - log.warn("NYI: drawString(AttributedCharacterIterator)"); - /* - try { - gen.writeln("BT"); - Shape imclip = getClip(); - writeClip(imclip); - establishColor(getColor()); - - AffineTransform trans = getTransform(); - trans.translate(x, y); - double[] vals = new double[6]; - trans.getMatrix(vals); - - for (char ch = iterator.first(); ch != CharacterIterator.DONE; - ch = iterator.next()) { - //Map attr = iterator.getAttributes(); - - gen.writeln(gen.formatDouble(vals[0]) + " " - + gen.formatDouble(vals[1]) + " " - + gen.formatDouble(vals[2]) + " " - + gen.formatDouble(vals[3]) + " " - + gen.formatDouble(vals[4]) + " " - + gen.formatDouble(vals[5]) + " " - + gen.formatDouble(vals[6]) + " Tm [" + ch - + "]"); - } - gen.writeln("ET"); - } catch (IOException ioe) { - handleIOException(ioe); - }*/ - } - - /** - * Fills the interior of a <code>Shape</code> using the settings of the - * <code>Graphics2D</code> context. The rendering attributes applied - * include the <code>Clip</code>, <code>Transform</code>, - * <code>Paint</code>, and <code>Composite</code>. - * @param s the <code>Shape</code> to be filled - * @see #setPaint - * @see java.awt.Graphics#setColor - * @see #transform - * @see #setTransform - * @see #setComposite - * @see #clip - * @see #setClip - */ - public void fill(Shape s) { - preparePainting(); - try { - gen.saveGraphicsState(); - - AffineTransform trans = getTransform(); - boolean newTransform = gen.getCurrentState().checkTransform(trans) - && !trans.isIdentity(); - - if (newTransform) { - gen.concatMatrix(trans); - } - Shape imclip = getClip(); - writeClip(imclip); - - establishColor(getColor()); - - applyPaint(getPaint(), true); - - gen.writeln("newpath"); - PathIterator iter = s.getPathIterator(IDENTITY_TRANSFORM); - processPathIterator(iter); - doDrawing(true, false, - iter.getWindingRule() == PathIterator.WIND_EVEN_ODD); - gen.restoreGraphicsState(); - } catch (IOException ioe) { - handleIOException(ioe); - } - } - - /** - * Commits a painting operation. - * @param fill filling - * @param stroke stroking - * @param nonzero true if the non-zero winding rule should be used when filling - * @exception IOException In case of an I/O problem - */ - protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) - throws IOException { - preparePainting(); - if (fill) { - if (stroke) { - if (!nonzero) { - gen.writeln("gsave fill grestore stroke"); - } else { - gen.writeln("gsave eofill grestore stroke"); - } - } else { - if (!nonzero) { - gen.writeln("fill"); - } else { - gen.writeln("eofill"); - } - } - } else { - // if(stroke) - gen.writeln("stroke"); - } - } - - /** - * Returns the device configuration associated with this - * <code>Graphics2D</code>. - * @return the device configuration - */ - public GraphicsConfiguration getDeviceConfiguration() { - return GraphicsEnvironment.getLocalGraphicsEnvironment(). - getDefaultScreenDevice().getDefaultConfiguration(); - } - - /** - * Used to create proper font metrics - */ - private Graphics2D fmg; - - { - BufferedImage bi = new BufferedImage(1, 1, - BufferedImage.TYPE_INT_ARGB); - - fmg = bi.createGraphics(); - } - - /** - * Sets the overriding font. - * @param font Font to set - */ - public void setOverrideFont(Font font) { - this.overrideFont = font; - } - - /** - * Gets the font metrics for the specified font. - * @return the font metrics for the specified font. - * @param f the specified font - * @see java.awt.Graphics#getFont - * @see java.awt.FontMetrics - * @see java.awt.Graphics#getFontMetrics() - */ - public java.awt.FontMetrics getFontMetrics(java.awt.Font f) { - return fmg.getFontMetrics(f); - } - - /** - * Sets the paint mode of this graphics context to alternate between - * this graphics context's current color and the new specified color. - * This specifies that logical pixel operations are performed in the - * XOR mode, which alternates pixels between the current color and - * a specified XOR color. - * <p> - * When drawing operations are performed, pixels which are the - * current color are changed to the specified color, and vice versa. - * <p> - * Pixels that are of colors other than those two colors are changed - * in an unpredictable but reversible manner; if the same figure is - * drawn twice, then all pixels are restored to their original values. - * @param c1 the XOR alternation color - */ - public void setXORMode(Color c1) { - log.warn("NYI: setXORMode"); - } - - - /** - * Copies an area of the component by a distance specified by - * <code>dx</code> and <code>dy</code>. From the point specified - * by <code>x</code> and <code>y</code>, this method - * copies downwards and to the right. To copy an area of the - * component to the left or upwards, specify a negative value for - * <code>dx</code> or <code>dy</code>. - * If a portion of the source rectangle lies outside the bounds - * of the component, or is obscured by another window or component, - * <code>copyArea</code> will be unable to copy the associated - * pixels. The area that is omitted can be refreshed by calling - * the component's <code>paint</code> method. - * @param x the <i>x</i> coordinate of the source rectangle. - * @param y the <i>y</i> coordinate of the source rectangle. - * @param width the width of the source rectangle. - * @param height the height of the source rectangle. - * @param dx the horizontal distance to copy the pixels. - * @param dy the vertical distance to copy the pixels. - */ - public void copyArea(int x, int y, int width, int height, int dx, - int dy) { - log.warn("NYI: copyArea"); - } - - /* --- for debugging - public void transform(AffineTransform tx) { - System.out.println("transform(" + toArray(tx) + ")"); - super.transform(zx); - } - - public void scale(double sx, double sy) { - System.out.println("scale(" + sx + ", " + sy + ")"); - super.scale(sx, sy); - } - - public void translate(double tx, double ty) { - System.out.println("translate(double " + tx + ", " + ty + ")"); - super.translate(tx, ty); - } - - public void translate(int tx, int ty) { - System.out.println("translate(int " + tx + ", " + ty + ")"); - super.translate(tx, ty); - } - */ - -} diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java index d54c87b8c..1464f4463 100644 --- a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java @@ -1,5 +1,5 @@ /*
- * Copyright 2005 The Apache Software Foundation.
+ * Copyright 2005-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,8 @@ import java.io.IOException; import org.apache.fop.render.Graphics2DAdapter;
import org.apache.fop.render.Graphics2DImagePainter;
import org.apache.fop.render.RendererContext;
+import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
+import org.apache.xmlgraphics.ps.PSGenerator;
/**
* Graphics2DAdapter implementation for PostScript.
@@ -75,7 +77,7 @@ public class PSGraphics2DAdapter implements Graphics2DAdapter { final boolean textAsShapes = false;
PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen);
- graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+ graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
AffineTransform transform = new AffineTransform();
// scale to viewbox
transform.translate(fx, fy);
diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java index bd3736eb5..9d6314f9d 100644 --- a/src/java/org/apache/fop/render/ps/PSImageUtils.java +++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java @@ -19,29 +19,20 @@ package org.apache.fop.render.ps; import java.awt.Dimension; -import java.awt.color.ColorSpace; import java.awt.geom.Rectangle2D; -import java.awt.image.ColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; import java.io.IOException; -import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.image.EPSImage; import org.apache.fop.image.FopImage; import org.apache.fop.image.JpegImage; -import org.apache.fop.util.ASCII85OutputStream; -import org.apache.fop.util.Finalizable; -import org.apache.fop.util.FlateEncodeOutputStream; -import org.apache.fop.util.RunLengthEncodeOutputStream; +import org.apache.xmlgraphics.ps.PSGenerator; /** * Utility code for rendering images in PostScript. */ -public class PSImageUtils { +public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils { /** logging instance */ protected static Log log = LogFactory.getLog(PSImageUtils.class); @@ -85,187 +76,6 @@ public class PSImageUtils { img.getColorSpace(), gen); } - private static void writeImage(byte[] img, - Dimension imgDim, String imgName, - Rectangle2D targetRect, - boolean isJPEG, ColorSpace colorSpace, - PSGenerator gen) throws IOException { - boolean iscolor = colorSpace.getType() != ColorSpace.CS_GRAY; - - gen.saveGraphicsState(); - gen.writeln(gen.formatDouble(targetRect.getX()) + " " - + gen.formatDouble(targetRect.getY()) + " translate"); - gen.writeln(gen.formatDouble(targetRect.getWidth()) + " " - + gen.formatDouble(targetRect.getHeight()) + " scale"); - - gen.commentln("%FOPBeginBitmap: " + imgName); - if (colorSpace.getType() == ColorSpace.TYPE_CMYK) { - gen.writeln("/DeviceCMYK setcolorspace"); - } else if (colorSpace.getType() == ColorSpace.CS_GRAY) { - gen.writeln("/DeviceGray setcolorspace"); - } else { - gen.writeln("/DeviceRGB setcolorspace"); - } - - gen.writeln("{{"); - // Template: (RawData is used for the EOF signal only) - // gen.write("/RawData currentfile <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"); - } - } diff --git a/src/java/org/apache/fop/render/ps/PSProcSets.java b/src/java/org/apache/fop/render/ps/PSProcSets.java deleted file mode 100644 index 56ee8fd0e..000000000 --- a/src/java/org/apache/fop/render/ps/PSProcSets.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.io.IOException; - -/** - * This class defines the basic resources (procsets) used by FOP's PostScript - * renderer and SVG transcoder. - * - * @author <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); - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java index dab429a13..a7e54b1e8 100644 --- a/src/java/org/apache/fop/render/ps/PSRenderer.java +++ b/src/java/org/apache/fop/render/ps/PSRenderer.java @@ -70,6 +70,12 @@ import org.apache.fop.render.RendererContext; import org.apache.fop.render.ps.extensions.PSSetupCode; import org.apache.fop.util.CharUtilities; +import org.apache.xmlgraphics.ps.DSCConstants; +import org.apache.xmlgraphics.ps.PSGenerator; +import org.apache.xmlgraphics.ps.PSProcSets; +import org.apache.xmlgraphics.ps.PSResource; +import org.apache.xmlgraphics.ps.PSState; + import org.w3c.dom.Document; /** diff --git a/src/java/org/apache/fop/render/ps/PSResource.java b/src/java/org/apache/fop/render/ps/PSResource.java deleted file mode 100644 index b68bcaf6d..000000000 --- a/src/java/org/apache/fop/render/ps/PSResource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -/** - * Represents a PostScript resource (file, font, procset etc.). - */ -public class PSResource { - - /** a file resource */ - public static final String TYPE_FILE = "file"; - /** a font resource */ - public static final String TYPE_FONT = "font"; - /** a procset resource */ - public static final String TYPE_PROCSET = "procset"; - - private String type; - private String name; - - /** - * Main constructor - * @param type type of the resource - * @param name name of the resource - */ - public PSResource(String type, String name) { - this.type = type; - this.name = name; - } - - /** @return the type of the resource */ - public String getType() { - return this.type; - } - - /** @return the name of the resource */ - public String getName() { - return this.name; - } - - /** @return the <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(); - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index e54bc4b49..e0ea029ad 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2005 The Apache Software Foundation. + * Copyright 1999-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,8 @@ import org.apache.fop.render.Renderer; import org.apache.fop.render.XMLHandler; import org.apache.fop.render.RendererContext; import org.apache.fop.svg.SVGUserAgent; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; +import org.apache.xmlgraphics.ps.PSGenerator; // Commons-Logging import org.apache.commons.logging.Log; @@ -251,10 +253,16 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { context.getUserAgent().getSourcePixelUnitToMillimeter(), new AffineTransform()); + PSGraphics2D graphics = new PSGraphics2D(strokeText, gen); + graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + GVTBuilder builder = new GVTBuilder(); + NativeTextHandler nativeTextHandler = null; BridgeContext ctx = new BridgeContext(ua); if (!strokeText) { - PSTextPainter textPainter = new PSTextPainter(psInfo.getFontInfo()); + nativeTextHandler = new NativeTextHandler(graphics, psInfo.getFontInfo()); + graphics.setCustomTextHandler(nativeTextHandler); + PSTextPainter textPainter = new PSTextPainter(nativeTextHandler); ctx.setTextPainter(textPainter); PSTextElementBridge tBridge = new PSTextElementBridge(textPainter); ctx.putBridge(tBridge); @@ -306,9 +314,6 @@ public class PSSVGHandler implements XMLHandler, PSRendererContextConstants { gen.concatMatrix(vals); }*/ - final boolean textAsShapes = false; - PSGraphics2D graphics = new PSGraphics2D(textAsShapes, gen); - graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); AffineTransform transform = new AffineTransform(); // scale to viewbox transform.translate(xOffset, yOffset); diff --git a/src/java/org/apache/fop/render/ps/PSState.java b/src/java/org/apache/fop/render/ps/PSState.java deleted file mode 100644 index 7421c5f28..000000000 --- a/src/java/org/apache/fop/render/ps/PSState.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 1999-2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.ps; - -import java.io.IOException; -import java.io.Serializable; -import java.util.List; -import java.awt.Color; -import java.awt.geom.AffineTransform; - -/** - * This class holds the current state of the PostScript interpreter. - * - * @author <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); - } - } - -} diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java index db654adb2..c42f3647b 100644 --- a/src/java/org/apache/fop/render/ps/PSTextPainter.java +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -31,9 +31,15 @@ import java.awt.Shape; import java.awt.Paint; import java.awt.Stroke; import java.awt.Color; +import java.io.IOException; import java.util.List; import java.util.Iterator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; + import org.apache.batik.dom.svg.SVGOMTextElement; import org.apache.batik.gvt.text.Mark; import org.apache.batik.gvt.TextPainter; @@ -42,8 +48,6 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; import org.apache.batik.gvt.text.TextPaintInfo; import org.apache.batik.gvt.font.GVTFontFamily; import org.apache.batik.gvt.renderer.StrokingTextPainter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; @@ -68,7 +72,8 @@ public class PSTextPainter implements TextPainter { /** the logger for this class */ protected Log log = LogFactory.getLog(PSTextPainter.class); - private FontInfo fontInfo; + private NativeTextHandler nativeTextHandler; + //private FontInfo fontInfo; /** * Use the stroking text painter to get the bounds and shape. @@ -79,10 +84,10 @@ public class PSTextPainter implements TextPainter { /** * Create a new PS text painter with the given font information. - * @param fontInfo the FontInfo object + * @param nativeTextHandler the NativeTextHandler instance used for text painting */ - public PSTextPainter(FontInfo fontInfo) { - this.fontInfo = fontInfo; + public PSTextPainter(NativeTextHandler nativeTextHandler) { + this.nativeTextHandler = nativeTextHandler; } /** @@ -188,7 +193,9 @@ public class PSTextPainter implements TextPainter { Object rcDel = aci.getAttribute( GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER); - if (!(rcDel instanceof SVGOMTextElement)) { + //Batik 1.6 returns null here which makes it impossible to determine whether this can + //be painted or not, i.e. fall back to stroking. :-( + if (/*rcDel != null &&*/ !(rcDel instanceof SVGOMTextElement)) { log.trace("-> spans found"); hasunsupported = true; //Filter spans } @@ -307,15 +314,17 @@ public class PSTextPainter implements TextPainter { } //Finally draw text - if (g2d instanceof PSGraphics2D) { - ((PSGraphics2D) g2d).setOverrideFont(font); - } + nativeTextHandler.setOverrideFont(font); try { - g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); - } finally { - if (g2d instanceof PSGraphics2D) { - ((PSGraphics2D) g2d).setOverrideFont(null); + try { + nativeTextHandler.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY())); + } catch (IOException ioe) { + if (g2d instanceof PSGraphics2D) { + ((PSGraphics2D)g2d).handleIOException(ioe); + } } + } finally { + nativeTextHandler.setOverrideFont(null); } loc.setLocation(loc.getX() + (double)advance, loc.getY()); return loc; @@ -370,6 +379,7 @@ public class PSTextPainter implements TextPainter { int weight = getWeight(aci); boolean found = false; + FontInfo fontInfo = nativeTextHandler.getFontInfo(); String fontFamily = null; List gvtFonts = (List) aci.getAttribute( GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES); diff --git a/src/java/org/apache/fop/render/ps/PSTranscoder.java b/src/java/org/apache/fop/render/ps/PSTranscoder.java index 62104ca26..5289f8272 100644 --- a/src/java/org/apache/fop/render/ps/PSTranscoder.java +++ b/src/java/org/apache/fop/render/ps/PSTranscoder.java @@ -18,6 +18,8 @@ package org.apache.fop.render.ps; +import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D; +import org.apache.xmlgraphics.java2d.ps.PSDocumentGraphics2D; /** * This class enables to transcode an input to a PostScript document. @@ -44,7 +46,6 @@ package org.apache.fop.render.ps; * millimeter conversion factor. * * @author <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); } diff --git a/src/java/org/apache/fop/util/ASCII85Constants.java b/src/java/org/apache/fop/util/ASCII85Constants.java deleted file mode 100644 index e8e3a8bd1..000000000 --- a/src/java/org/apache/fop/util/ASCII85Constants.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -/** - * This interface defines constants used by the ASCII85 filters. - * - * @author <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; - */ - -} - - diff --git a/src/java/org/apache/fop/util/ASCII85InputStream.java b/src/java/org/apache/fop/util/ASCII85InputStream.java deleted file mode 100644 index d9b3fae91..000000000 --- a/src/java/org/apache/fop/util/ASCII85InputStream.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.InputStream; -import java.io.IOException; - -/** - * This class applies a ASCII85 decoding to the stream. - * <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; - } - } - -} - - diff --git a/src/java/org/apache/fop/util/ASCII85OutputStream.java b/src/java/org/apache/fop/util/ASCII85OutputStream.java deleted file mode 100644 index 02bc613dc..000000000 --- a/src/java/org/apache/fop/util/ASCII85OutputStream.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.OutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -/** - * This class applies a ASCII85 encoding to the stream. - * - * @version $Id$ - */ -public class ASCII85OutputStream extends FilterOutputStream - implements ASCII85Constants, Finalizable { - - private static final boolean DEBUG = false; - - private int pos = 0; - private long buffer = 0; - private int posinline = 0; - private int bw = 0; - - /** @see java.io.FilterOutputStream **/ - public ASCII85OutputStream(OutputStream out) { - super(out); - } - - /** @see java.io.FilterOutputStream **/ - public void write(int b) throws IOException { - if (pos == 0) { - buffer += (b << 24) & 0xff000000L; - } else if (pos == 1) { - buffer += (b << 16) & 0xff0000L; - } else if (pos == 2) { - buffer += (b << 8) & 0xff00L; - } else { - buffer += b & 0xffL; - } - pos++; - - if (pos > 3) { - checkedWrite(convertWord(buffer)); - buffer = 0; - pos = 0; - } - } - - /* UNUSED ATM - private void checkedWrite(int b) throws IOException { - if (posinline == 80) { - out.write(EOL); bw++; - posinline = 0; - } - checkedWrite(b); - posinline++; - bw++; - }*/ - - private void checkedWrite(byte[] buf) throws IOException { - checkedWrite(buf, buf.length, false); - } - - private void checkedWrite(byte[] buf, boolean nosplit) throws IOException { - checkedWrite(buf, buf.length, nosplit); - } - - private void checkedWrite(byte[] buf , int len) throws IOException { - checkedWrite(buf, len, false); - } - - private void checkedWrite(byte[] buf , int len, boolean nosplit) throws IOException { - if (posinline + len > 80) { - int firstpart = (nosplit ? 0 : len - (posinline + len - 80)); - if (firstpart > 0) { - out.write(buf, 0, firstpart); - } - out.write(EOL); bw++; - int rest = len - firstpart; - if (rest > 0) { - out.write(buf, firstpart, rest); - } - posinline = rest; - } else { - out.write(buf, 0, len); - posinline += len; - } - bw += len; - } - - /** - * This converts a 32 bit value (4 bytes) into 5 bytes using base 85. - * each byte in the result starts with zero at the '!' character so - * the resulting base85 number fits into printable ascii chars - * - * @param word the 32 bit unsigned (hence the long datatype) word - * @return 5 bytes (or a single byte of the 'z' character for word - * values of 0) - */ - private byte[] convertWord(long word) { - word = word & 0xffffffff; - - if (word == 0) { - return ZERO_ARRAY; - } else { - if (word < 0) { - word = -word; - } - byte c1 = - (byte)((word - / POW85[0]) & 0xFF); - byte c2 = - (byte)(((word - (c1 * POW85[0])) - / POW85[1]) & 0xFF); - byte c3 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1])) - / POW85[2]) & 0xFF); - byte c4 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1]) - - (c3 * POW85[2])) - / POW85[3]) & 0xFF); - byte c5 = - (byte)(((word - (c1 * POW85[0]) - - (c2 * POW85[1]) - - (c3 * POW85[2]) - - (c4 * POW85[3]))) - & 0xFF); - - byte[] ret = { - (byte)(c1 + START), (byte)(c2 + START), - (byte)(c3 + START), (byte)(c4 + START), - (byte)(c5 + START) - }; - - if (DEBUG) { - for (int i = 0; i < ret.length; i++) { - if (ret[i] < 33 || ret[i] > 117) { - System.out.println("Illegal char value " - + new Integer(ret[i])); - } - } - } - return ret; - } - } - - /** @see Finalizable **/ - public void finalizeStream() throws IOException { - // now take care of the trailing few bytes. - // with n leftover bytes, we append 0 bytes to make a full group of 4 - // then convert like normal (except not applying the special zero rule) - // and write out the first n+1 bytes from the result - if (pos > 0) { - int rest = pos; - /* - byte[] lastdata = new byte[4]; - int i = 0; - for (int j = 0; j < 4; j++) { - if (j < rest) { - lastdata[j] = data[i++]; - } else { - lastdata[j] = 0; - } - } - - long val = ((lastdata[0] << 24) & 0xff000000L) - + ((lastdata[1] << 16) & 0xff0000L) - + ((lastdata[2] << 8) & 0xff00L) - + (lastdata[3] & 0xffL); - */ - - byte[] conv; - // special rule for handling zeros at the end - if (buffer != 0) { - conv = convertWord(buffer); - } else { - conv = new byte[5]; - for (int j = 0; j < 5; j++) { - conv[j] = (byte)'!'; - } - } - // assert rest+1 <= 5 - checkedWrite(conv, rest + 1); - } - // finally write the two character end of data marker - checkedWrite(EOD, true); - - flush(); - if (out instanceof Finalizable) { - ((Finalizable)out).finalizeStream(); - } - } - - /** @see java.io.FilterOutputStream **/ - public void close() throws IOException { - finalizeStream(); - super.close(); - } - -} - - diff --git a/src/java/org/apache/fop/util/ASCIIHexOutputStream.java b/src/java/org/apache/fop/util/ASCIIHexOutputStream.java deleted file mode 100644 index d2ac48a3e..000000000 --- a/src/java/org/apache/fop/util/ASCIIHexOutputStream.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.OutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; - -/** - * This class applies a ASCII Hex encoding to the stream. - * - * @author <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(); - } - - -} - - diff --git a/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java b/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java index 5fd68fd2b..3d95d91a3 100644 --- a/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java +++ b/src/java/org/apache/fop/util/ContentHandlerFactoryRegistry.java @@ -24,7 +24,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.fop.util.Service; +import org.apache.xmlgraphics.util.Service; /** * This class holds references to various XML handlers used by FOP. It also @@ -101,12 +101,13 @@ public class ContentHandlerFactoryRegistry { Iterator providers = Service.providers(ContentHandlerFactory.class); if (providers != null) { while (providers.hasNext()) { - String str = (String)providers.next(); + ContentHandlerFactory factory = (ContentHandlerFactory)providers.next(); try { if (log.isDebugEnabled()) { - log.debug("Dynamically adding ContentHandlerFactory: " + str); + log.debug("Dynamically adding ContentHandlerFactory: " + + factory.getClass().getName()); } - addContentHandlerFactory(str); + addContentHandlerFactory(factory); } catch (IllegalArgumentException e) { log.error("Error while adding ContentHandlerFactory", e); } diff --git a/src/java/org/apache/fop/util/Finalizable.java b/src/java/org/apache/fop/util/Finalizable.java deleted file mode 100644 index 365f0cae6..000000000 --- a/src/java/org/apache/fop/util/Finalizable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -/** - * This interface is used for special FilteredOutputStream classes that won't - * be closed (since this causes the target OutputStream to be closed, too) but - * where flush() is not enough, for example because a final marker has to be - * written to the target stream. - * - * @author <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; - -} diff --git a/src/java/org/apache/fop/util/FlateEncodeOutputStream.java b/src/java/org/apache/fop/util/FlateEncodeOutputStream.java deleted file mode 100644 index 9789929e4..000000000 --- a/src/java/org/apache/fop/util/FlateEncodeOutputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * This class applies a FlateEncode filter to the stream. It is basically the - * normal DeflaterOutputStream except now also implementing the Finalizable - * interface. - * - * @author <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(); - } - } - -} - - diff --git a/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java b/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java deleted file mode 100644 index f3cd225be..000000000 --- a/src/java/org/apache/fop/util/RunLengthEncodeOutputStream.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.FilterOutputStream; -import java.io.OutputStream; -import java.io.IOException; - - -/** - * This class applies a RunLengthEncode filter to the stream. - * - * @author <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(); - } - -} - diff --git a/src/java/org/apache/fop/util/Service.java b/src/java/org/apache/fop/util/Service.java deleted file mode 100644 index 717b0f47f..000000000 --- a/src/java/org/apache/fop/util/Service.java +++ /dev/null @@ -1,113 +0,0 @@ -/*
- * Copyright 1999-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-//code stolen from org.apache.batik.util and modified slightly
-//does what sun.misc.Service probably does, but it cannot be relied on.
-//hopefully will be part of standard jdk sometime.
-
-/**
- * This class loads services present in the class path.
- */
-public class Service {
-
- private static Map providerMap = new java.util.Hashtable();
-
- public static synchronized Iterator providers(Class cls) {
- ClassLoader cl = cls.getClassLoader();
- // null if loaded by bootstrap class loader
- if (cl == null) {
- cl = ClassLoader.getSystemClassLoader();
- }
- String serviceFile = "META-INF/services/" + cls.getName();
-
- // log.debug("File: " + serviceFile);
-
- List lst = (List)providerMap.get(serviceFile);
- if (lst != null) {
- return lst.iterator();
- }
-
- lst = new java.util.Vector();
- providerMap.put(serviceFile, lst);
-
- Enumeration e;
- try {
- e = cl.getResources(serviceFile);
- } catch (IOException ioe) {
- return lst.iterator();
- }
-
- while (e.hasMoreElements()) {
- try {
- java.net.URL u = (java.net.URL)e.nextElement();
- //log.debug("URL: " + u);
-
- InputStream is = u.openStream();
- Reader r = new InputStreamReader(is, "UTF-8");
- BufferedReader br = new BufferedReader(r);
-
- String line = br.readLine();
- while (line != null) {
- try {
- // First strip any comment...
- int idx = line.indexOf('#');
- if (idx != -1) {
- line = line.substring(0, idx);
- }
-
- // Trim whitespace.
- line = line.trim();
-
- // If nothing left then loop around...
- if (line.length() == 0) {
- line = br.readLine();
- continue;
- }
- // log.debug("Line: " + line);
-
- // Try and load the class
- // Object obj = cl.loadClass(line).newInstance();
- // stick it into our vector...
- lst.add(line);
- } catch (Exception ex) {
- // Just try the next line
- }
-
- line = br.readLine();
- }
- } catch (Exception ex) {
- // Just try the next file...
- }
-
- }
- return lst.iterator();
- }
-
- }
\ No newline at end of file diff --git a/src/java/org/apache/fop/util/SubInputStream.java b/src/java/org/apache/fop/util/SubInputStream.java deleted file mode 100644 index 83b146402..000000000 --- a/src/java/org/apache/fop/util/SubInputStream.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.util; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * This class is a FilterInputStream descendant that reads from an underlying InputStream - * up to a defined number of bytes or the end of the underlying stream. Closing this InputStream - * will not result in the underlying InputStream to be closed, too. - * <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; - } -} |