diff options
author | Jeremias Maerki <jeremias@apache.org> | 2008-12-09 15:00:35 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2008-12-09 15:00:35 +0000 |
commit | a6ddced309701a1ca8d79a9e7bec3288afba2cc8 (patch) | |
tree | c3d2bcfe7277246d9a2acc3675721a99f4de5727 /src/java/org/apache/fop/render | |
parent | 9d339f0968314f0cfcc4a720628fed1845292ce1 (diff) | |
parent | f9d4720b99f5e0fb423b097d7207dfab446d911c (diff) | |
download | xmlgraphics-fop-a6ddced309701a1ca8d79a9e7bec3288afba2cc8.tar.gz xmlgraphics-fop-a6ddced309701a1ca8d79a9e7bec3288afba2cc8.zip |
Merge from Trunk revisions 719662 - 724689.
Conflict for ImageHandler interface resolved by renaming Trunk's ImageHandler to ImageHandlerBase and extending the other ImageHandler from that.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@724729 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/render')
112 files changed, 3004 insertions, 12824 deletions
diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java index fb62e653d..731f0bae2 100644 --- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -21,9 +21,7 @@ package org.apache.fop.render; // Java import java.awt.Dimension; -import java.awt.Graphics2D; import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; import java.io.IOException; import org.w3c.dom.Document; @@ -37,7 +35,11 @@ import org.apache.batik.gvt.GraphicsNode; import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; import org.apache.xmlgraphics.util.QName; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.image.loader.batik.BatikUtil; +import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl; import org.apache.fop.render.RendererContext.RendererContextWrapper; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; @@ -54,6 +56,9 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC protected static final QName CONVERSION_MODE = new QName( ExtensionElementMapping.URI, null, "conversion-mode"); + /** "bitmap" value for the "conversion-mode" extension attribute. */ + protected static final String BITMAP = "bitmap"; + /** {@inheritDoc} */ public void handleXML(RendererContext context, Document doc, String ns) throws Exception { @@ -64,65 +69,101 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC } /** - * Render the SVG document. - * @param context the renderer context - * @param doc the SVG document - * @throws IOException In case of an I/O error while painting the image + * Creates a graphics 2D image painter implementation + * + * @param root the batik graphics node root + * @param ctx the batik bridge context + * @param imageSize the image size + * @return a new graphics 2D image painter implementation */ - protected void renderSVGDocument(final RendererContext context, - final Document doc) throws IOException { - updateRendererContext(context); - final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(context); - int x = wrappedContext.getCurrentXPosition(); - int y = wrappedContext.getCurrentYPosition(); + protected Graphics2DImagePainter createGraphics2DImagePainter( + GraphicsNode root, BridgeContext ctx, Dimension imageSize) { + return new Graphics2DImagePainterImpl(root, ctx, imageSize); + } - //Prepare - SVGUserAgent ua = new SVGUserAgent( - context.getUserAgent(), - new AffineTransform()); + /** + * Builds the GVT root + * + * @param rendererContext the renderer context + * @param ctx the batik bridge context + * @param doc the document + * @return a built GVT root tree + */ + protected GraphicsNode buildGraphicsNode( + FOUserAgent userAgent, BridgeContext ctx, Document doc) { GVTBuilder builder = new GVTBuilder(); - final BridgeContext ctx = new BridgeContext(ua); - - //Build the GVT tree final GraphicsNode root; try { root = builder.build(ctx, doc); } catch (Exception e) { - SVGEventProducer eventProducer = SVGEventProducer.Provider.get( - context.getUserAgent().getEventBroadcaster()); - eventProducer.svgNotBuilt(this, e, getDocumentURI(doc)); - return; + EventBroadcaster eventBroadcaster + = userAgent.getEventBroadcaster(); + SVGEventProducer eventProducer = SVGEventProducer.Provider.get(eventBroadcaster); + final String uri = getDocumentURI(doc); + eventProducer.svgNotBuilt(this, e, uri); + return null; } + return root; + } - //Create the painter - Graphics2DImagePainter painter = new Graphics2DImagePainter() { + /** + * Returns the image size + * @param wrappedContext renderer context wrapper + * + * @return the image size + */ + protected Dimension getImageSize(RendererContextWrapper wrappedContext) { + final int width = wrappedContext.getWidth(); + final int height = wrappedContext.getHeight(); + return new Dimension(width, height); + } - public void paint(Graphics2D g2d, Rectangle2D area) { - // If no viewbox is defined in the svg file, a viewbox of 100x100 is - // assumed, as defined in SVGUserAgent.getViewportSize() - float iw = (float) ctx.getDocumentSize().getWidth(); - float ih = (float) ctx.getDocumentSize().getHeight(); - float w = (float) area.getWidth(); - float h = (float) area.getHeight(); - g2d.scale(w / iw, h / ih); + /** + * Render the SVG document. + * + * @param rendererContext the renderer context + * @param doc the SVG document + * @throws IOException In case of an I/O error while painting the image + */ + protected void renderSVGDocument(final RendererContext rendererContext, + final Document doc) throws IOException { + updateRendererContext(rendererContext); + + //Prepare + FOUserAgent userAgent = rendererContext.getUserAgent(); + SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform()); + + //Create Batik BridgeContext + final BridgeContext bridgeContext = new BridgeContext(svgUserAgent); - root.paint(g2d); - } + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(doc); - public Dimension getImageSize() { - return new Dimension(wrappedContext.getWidth(), wrappedContext.getHeight()); - } + //Build the GVT tree + final GraphicsNode root = buildGraphicsNode(userAgent, bridgeContext, clonedDoc); - }; + // Create Graphics2DImagePainter + final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext( + rendererContext); + Dimension imageSize = getImageSize(wrappedContext); + final Graphics2DImagePainter painter = createGraphics2DImagePainter( + root, bridgeContext, imageSize); //Let the painter paint the SVG on the Graphics2D instance - Graphics2DAdapter adapter = context.getRenderer().getGraphics2DAdapter(); - adapter.paintImage(painter, context, - x, y, wrappedContext.getWidth(), wrappedContext.getHeight()); + Graphics2DAdapter g2dAdapter = rendererContext.getRenderer().getGraphics2DAdapter(); + + //Paint the image + final int x = wrappedContext.getCurrentXPosition(); + final int y = wrappedContext.getCurrentYPosition(); + final int width = wrappedContext.getWidth(); + final int height = wrappedContext.getHeight(); + g2dAdapter.paintImage(painter, rendererContext, x, y, width, height); } /** * Gets the document URI from a Document instance if possible. + * * @param doc the Document * @return the URI or null */ @@ -138,6 +179,7 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC /** * Override this method to update the renderer context if it needs special settings for * certain conditions. + * * @param context the renderer context */ protected void updateRendererContext(RendererContext context) { diff --git a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java index 5861fb042..ee18dff0d 100644 --- a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java @@ -54,8 +54,8 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { protected BufferedImage paintToBufferedImage( org.apache.xmlgraphics.java2d.Graphics2DImagePainter painter, RendererContextWrapper context, int resolution, boolean gray, boolean withAlpha) { - int bmw = (int)Math.ceil(UnitConv.mpt2px(context.getWidth(), resolution)); - int bmh = (int)Math.ceil(UnitConv.mpt2px(context.getHeight(), resolution)); + int bmw = mpt2px(context.getWidth(), resolution); + int bmh = mpt2px(context.getHeight(), resolution); BufferedImage bi; if (gray) { if (withAlpha) { @@ -102,6 +102,17 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter { return bi; } + /** + * Converts millipoints to pixels + * + * @param unit the unit to convert in mpts + * @param resolution the target resolution + * @return the converted unit in pixels + */ + protected int mpt2px(int unit, int resolution) { + return (int)Math.ceil(UnitConv.mpt2px(unit, resolution)); + } + private static BufferedImage createGrayBufferedImageWithAlpha(int width, int height) { BufferedImage bi; boolean alphaPremultiplied = true; diff --git a/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java b/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java new file mode 100644 index 000000000..4196a1b19 --- /dev/null +++ b/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.xmlgraphics.image.loader.Image; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.util.Service; + +/** + * This class holds references to various image handlers used by the renderers. It also + * supports automatic discovery of additional handlers available through + * the class path. + */ +public abstract class AbstractImageHandlerRegistry { + + /** the logger */ + private static Log log = LogFactory.getLog(AbstractImageHandlerRegistry.class); + + private static final Comparator HANDLER_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + ImageHandlerBase h1 = (ImageHandlerBase)o1; + ImageHandlerBase h2 = (ImageHandlerBase)o2; + return h1.getPriority() - h2.getPriority(); + } + }; + + /** Map containing image handlers for various MIME types */ + private final Map/*<Class, ImageHandler>*/ handlers + = new java.util.HashMap/*<Class, ImageHandler>*/(); + + /** List containing the same handlers as above but ordered by priority */ + private final List/*<ImageHandler>*/ handlerList + = new java.util.LinkedList/*<ImageHandler>*/(); + + /** Sorted Set of registered handlers */ + private ImageFlavor[] supportedFlavors = new ImageFlavor[0]; + + private int handlerRegistrations; + private int lastSync; + + /** + * Default constructor. + */ + public AbstractImageHandlerRegistry() { + discoverHandlers(); + } + + /** + * Add an ImageHandler. The handler itself is inspected to find out what it supports. + * @param classname the fully qualified class name + */ + public void addHandler(String classname) { + try { + ImageHandlerBase handlerInstance + = (ImageHandlerBase)Class.forName(classname).newInstance(); + addHandler(handlerInstance); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Could not find " + + classname); + } catch (InstantiationException e) { + throw new IllegalArgumentException("Could not instantiate " + + classname); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Could not access " + + classname); + } catch (ClassCastException e) { + throw new IllegalArgumentException(classname + + " is not an " + + getHandlerClass().getName()); + } + } + + /** + * Add an image handler. The handler itself is inspected to find out what it supports. + * @param handler the ImageHandler instance + */ + public synchronized void addHandler(ImageHandlerBase handler) { + this.handlers.put(handler.getSupportedImageClass(), handler); + + //Sorted insert + ListIterator iter = this.handlerList.listIterator(); + while (iter.hasNext()) { + ImageHandlerBase h = (ImageHandlerBase)iter.next(); + if (getHandlerComparator().compare(handler, h) < 0) { + iter.previous(); + break; + } + } + iter.add(handler); + this.handlerRegistrations++; + } + + /** + * Returns an ImageHandler which handles an specific image type given the MIME type + * of the image. + * @param img the Image to be handled + * @return the ImageHandler responsible for handling the image or null if none is available + */ + public ImageHandlerBase getHandler(Image img) { + return getHandler(img.getClass()); + } + + /** + * Returns an ImageHandler which handles an specific image type given the MIME type + * of the image. + * @param imageClass the Image subclass for which to get a handler + * @return the ImageHandler responsible for handling the image or null if none is available + */ + public synchronized ImageHandlerBase getHandler(Class imageClass) { + ImageHandlerBase handler = null; + Class cl = imageClass; + while (cl != null) { + handler = (ImageHandlerBase)handlers.get(cl); + if (handler != null) { + break; + } + cl = cl.getSuperclass(); + } + return handler; + } + + /** + * Returns the ordered array of supported image flavors. + * @return the array of image flavors + */ + public synchronized ImageFlavor[] getSupportedFlavors() { + if (this.lastSync != this.handlerRegistrations) { + //Extract all ImageFlavors into a single array + List flavors = new java.util.ArrayList(); + Iterator iter = this.handlerList.iterator(); + while (iter.hasNext()) { + ImageFlavor[] f = ((ImageHandlerBase)iter.next()).getSupportedImageFlavors(); + for (int i = 0; i < f.length; i++) { + flavors.add(f[i]); + } + } + this.supportedFlavors = (ImageFlavor[])flavors.toArray(new ImageFlavor[flavors.size()]); + this.lastSync = this.handlerRegistrations; + } + return this.supportedFlavors; + } + + /** + * Discovers ImageHandler implementations through the classpath and dynamically + * registers them. + */ + private void discoverHandlers() { + // add mappings from available services + Class imageHandlerClass = getHandlerClass(); + Iterator providers = Service.providers(imageHandlerClass); + if (providers != null) { + while (providers.hasNext()) { + ImageHandlerBase handler = (ImageHandlerBase)providers.next(); + try { + if (log.isDebugEnabled()) { + log.debug("Dynamically adding ImageHandler: " + + handler.getClass().getName()); + } + addHandler(handler); + } catch (IllegalArgumentException e) { + log.error("Error while adding ImageHandler", e); + } + + } + } + } + + /** + * Returns the ImageHandler comparator + * + * @return the ImageHandler comparator + */ + public Comparator getHandlerComparator() { + return HANDLER_COMPARATOR; + } + + /** + * Returns the ImageHandler implementing class + * + * @return the ImageHandler implementing class + */ + public abstract Class getHandlerClass(); +} diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index c57a9d566..2e04f2d85 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -26,13 +26,7 @@ import java.awt.geom.Rectangle2D; import java.util.List; import java.util.Map; -import org.w3c.dom.Document; - import org.apache.batik.parser.AWTTransformProducer; - -import org.apache.xmlgraphics.image.loader.ImageSize; -import org.apache.xmlgraphics.util.QName; - import org.apache.fop.area.Area; import org.apache.fop.area.Block; import org.apache.fop.area.BlockViewport; @@ -48,7 +42,10 @@ import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.FontMetrics; import org.apache.fop.traits.BorderProps; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.util.UnitConv; +import org.w3c.dom.Document; /** * Abstract base class for renderers like PDF and PostScript where many painting operations @@ -270,6 +267,11 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { drawBorders(borderRect, bpsBefore, bpsAfter, bpsStart, bpsEnd); } + private static final int BEFORE = 0; + private static final int END = 1; + private static final int AFTER = 2; + private static final int START = 3; + /** * Draws borders. * @param borderRect the border rectangle @@ -280,45 +282,46 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { */ protected void drawBorders(Rectangle2D.Float borderRect, BorderProps bpsBefore, BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) { + //TODO generalize each of the four conditions into using a parameterized drawBorder() + boolean[] border = new boolean[] { + (bpsBefore != null), (bpsEnd != null), + (bpsAfter != null), (bpsStart != null)}; float startx = borderRect.x; float starty = borderRect.y; float width = borderRect.width; float height = borderRect.height; - boolean[] b = new boolean[] { - (bpsBefore != null), (bpsEnd != null), - (bpsAfter != null), (bpsStart != null)}; - if (!b[0] && !b[1] && !b[2] && !b[3]) { - return; - } - float[] bw = new float[] { - (b[0] ? bpsBefore.width / 1000f : 0.0f), - (b[1] ? bpsEnd.width / 1000f : 0.0f), - (b[2] ? bpsAfter.width / 1000f : 0.0f), - (b[3] ? bpsStart.width / 1000f : 0.0f)}; + float[] borderWidth = new float[] { + (border[BEFORE] ? bpsBefore.width / 1000f : 0.0f), + (border[END] ? bpsEnd.width / 1000f : 0.0f), + (border[AFTER] ? bpsAfter.width / 1000f : 0.0f), + (border[START] ? bpsStart.width / 1000f : 0.0f)}; float[] clipw = new float[] { BorderProps.getClippedWidth(bpsBefore) / 1000f, BorderProps.getClippedWidth(bpsEnd) / 1000f, BorderProps.getClippedWidth(bpsAfter) / 1000f, BorderProps.getClippedWidth(bpsStart) / 1000f}; - starty += clipw[0]; - height -= clipw[0]; - height -= clipw[2]; - startx += clipw[3]; - width -= clipw[3]; - width -= clipw[1]; + starty += clipw[BEFORE]; + height -= clipw[BEFORE]; + height -= clipw[AFTER]; + startx += clipw[START]; + width -= clipw[START]; + width -= clipw[END]; boolean[] slant = new boolean[] { - (b[3] && b[0]), (b[0] && b[1]), (b[1] && b[2]), (b[2] && b[3])}; + (border[START] && border[BEFORE]), + (border[BEFORE] && border[END]), + (border[END] && border[AFTER]), + (border[AFTER] && border[START])}; if (bpsBefore != null) { endTextObject(); float sx1 = startx; - float sx2 = (slant[0] ? sx1 + bw[3] - clipw[3] : sx1); + float sx2 = (slant[BEFORE] ? sx1 + borderWidth[START] - clipw[START] : sx1); float ex1 = startx + width; - float ex2 = (slant[1] ? ex1 - bw[1] + clipw[1] : ex1); - float outery = starty - clipw[0]; - float clipy = outery + clipw[0]; - float innery = outery + bw[0]; + float ex2 = (slant[END] ? ex1 - borderWidth[END] + clipw[END] : ex1); + float outery = starty - clipw[BEFORE]; + float clipy = outery + clipw[BEFORE]; + float innery = outery + borderWidth[BEFORE]; saveGraphicsState(); moveTo(sx1, clipy); @@ -326,10 +329,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { float ex1a = ex1; if (bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) { - sx1a -= clipw[3]; + sx1a -= clipw[START]; } if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { - ex1a += clipw[1]; + ex1a += clipw[END]; } lineTo(sx1a, outery); lineTo(ex1a, outery); @@ -347,12 +350,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { endTextObject(); float sy1 = starty; - float sy2 = (slant[1] ? sy1 + bw[0] - clipw[0] : sy1); + float sy2 = (slant[END] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1); float ey1 = starty + height; - float ey2 = (slant[2] ? ey1 - bw[2] + clipw[2] : ey1); - float outerx = startx + width + clipw[1]; - float clipx = outerx - clipw[1]; - float innerx = outerx - bw[1]; + float ey2 = (slant[AFTER] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1); + float outerx = startx + width + clipw[END]; + float clipx = outerx - clipw[END]; + float innerx = outerx - borderWidth[END]; saveGraphicsState(); moveTo(clipx, sy1); @@ -360,10 +363,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { float ey1a = ey1; if (bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { - sy1a -= clipw[0]; + sy1a -= clipw[BEFORE]; } if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { - ey1a += clipw[2]; + ey1a += clipw[AFTER]; } lineTo(outerx, sy1a); lineTo(outerx, ey1a); @@ -380,12 +383,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { endTextObject(); float sx1 = startx; - float sx2 = (slant[3] ? sx1 + bw[3] - clipw[3] : sx1); + float sx2 = (slant[START] ? sx1 + borderWidth[AFTER] - clipw[AFTER] : sx1); float ex1 = startx + width; - float ex2 = (slant[2] ? ex1 - bw[1] + clipw[1] : ex1); - float outery = starty + height + clipw[2]; - float clipy = outery - clipw[2]; - float innery = outery - bw[2]; + float ex2 = (slant[AFTER] ? ex1 - borderWidth[END] + clipw[END] : ex1); + float outery = starty + height + clipw[AFTER]; + float clipy = outery - clipw[AFTER]; + float innery = outery - borderWidth[AFTER]; saveGraphicsState(); moveTo(ex1, clipy); @@ -393,10 +396,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { float ex1a = ex1; if (bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { if (bpsStart != null && bpsStart.mode == BorderProps.COLLAPSE_OUTER) { - sx1a -= clipw[3]; + sx1a -= clipw[START]; } if (bpsEnd != null && bpsEnd.mode == BorderProps.COLLAPSE_OUTER) { - ex1a += clipw[1]; + ex1a += clipw[END]; } lineTo(ex1a, outery); lineTo(sx1a, outery); @@ -413,12 +416,12 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { endTextObject(); float sy1 = starty; - float sy2 = (slant[0] ? sy1 + bw[0] - clipw[0] : sy1); + float sy2 = (slant[BEFORE] ? sy1 + borderWidth[BEFORE] - clipw[BEFORE] : sy1); float ey1 = sy1 + height; - float ey2 = (slant[3] ? ey1 - bw[2] + clipw[2] : ey1); - float outerx = startx - clipw[3]; - float clipx = outerx + clipw[3]; - float innerx = outerx + bw[3]; + float ey2 = (slant[START] ? ey1 - borderWidth[AFTER] + clipw[AFTER] : ey1); + float outerx = startx - clipw[START]; + float clipx = outerx + clipw[START]; + float innerx = outerx + borderWidth[START]; saveGraphicsState(); moveTo(clipx, ey1); @@ -426,10 +429,10 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { float ey1a = ey1; if (bpsStart.mode == BorderProps.COLLAPSE_OUTER) { if (bpsBefore != null && bpsBefore.mode == BorderProps.COLLAPSE_OUTER) { - sy1a -= clipw[0]; + sy1a -= clipw[BEFORE]; } if (bpsAfter != null && bpsAfter.mode == BorderProps.COLLAPSE_OUTER) { - ey1a += clipw[2]; + ey1a += clipw[AFTER]; } lineTo(outerx, ey1a); lineTo(outerx, sy1a); @@ -451,10 +454,6 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { * rendered */ protected void renderInlineAreaBackAndBorders(InlineArea area) { - float x = currentIPPosition / 1000f; - float y = (currentBPPosition + area.getOffset()) / 1000f; - float width = area.getIPD() / 1000f; - float height = area.getBPD() / 1000f; float borderPaddingStart = area.getBorderAndPaddingWidthStart() / 1000f; float borderPaddingBefore = area.getBorderAndPaddingWidthBefore() / 1000f; float bpwidth = borderPaddingStart @@ -462,12 +461,15 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { float bpheight = borderPaddingBefore + (area.getBorderAndPaddingWidthAfter() / 1000f); + float height = area.getBPD() / 1000f; if (height != 0.0f || bpheight != 0.0f && bpwidth != 0.0f) { + float x = currentIPPosition / 1000f; + float y = (currentBPPosition + area.getOffset()) / 1000f; + float width = area.getIPD() / 1000f; drawBackAndBorders(area, x, y - borderPaddingBefore , width + bpwidth , height + bpheight); } - } /** Constant for the fox:transform extension attribute */ @@ -483,26 +485,24 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { int saveBP = currentBPPosition; CTM ctm = bv.getCTM(); - int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore(); - //This is the content-rect - float width = bv.getIPD() / 1000f; - float height = bv.getBPD() / 1000f; - if (bv.getPositioning() == Block.ABSOLUTE - || bv.getPositioning() == Block.FIXED) { + int positioning = bv.getPositioning(); + if (positioning == Block.ABSOLUTE || positioning == Block.FIXED) { //For FIXED, we need to break out of the current viewports to the //one established by the page. We save the state stack for restoration //after the block-container has been painted. See below. List breakOutList = null; - if (bv.getPositioning() == Block.FIXED) { + if (positioning == Block.FIXED) { breakOutList = breakOutOfStateStack(); } AffineTransform positionTransform = new AffineTransform(); positionTransform.translate(bv.getXOffset(), bv.getYOffset()); + int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); + //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle positionTransform.translate(-borderPaddingStart, -borderPaddingBefore); @@ -514,39 +514,62 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { positionTransform.concatenate(freeTransform); } - saveGraphicsState(); //Viewport position - concatenateTransformationMatrix(UnitConv.mptToPt(positionTransform)); + if (!positionTransform.isIdentity()) { + establishTransformationMatrix(positionTransform); + } + + //This is the content-rect + float width = bv.getIPD() / 1000f; + float height = bv.getBPD() / 1000f; //Background and borders - float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; - float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f; - drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight); + float borderPaddingWidth + = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; + float borderPaddingHeight + = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f; + drawBackAndBorders(bv, 0, 0, width + borderPaddingWidth, height + borderPaddingHeight); //Shift to content rectangle after border painting AffineTransform contentRectTransform = new AffineTransform(); contentRectTransform.translate(borderPaddingStart, borderPaddingBefore); - concatenateTransformationMatrix(UnitConv.mptToPt(contentRectTransform)); + + if (!contentRectTransform.isIdentity()) { + establishTransformationMatrix(contentRectTransform); + } //Clipping if (bv.getClip()) { clipRect(0f, 0f, width, height); } - saveGraphicsState(); //Set up coordinate system for content rectangle AffineTransform contentTransform = ctm.toAffineTransform(); - concatenateTransformationMatrix(UnitConv.mptToPt(contentTransform)); + if (!contentTransform.isIdentity()) { + establishTransformationMatrix(contentTransform); + } currentIPPosition = 0; currentBPPosition = 0; renderBlocks(bv, children); - restoreGraphicsState(); - restoreGraphicsState(); + if (!contentTransform.isIdentity()) { + restoreGraphicsState(); + } + + if (!contentRectTransform.isIdentity()) { + restoreGraphicsState(); + } + + if (!positionTransform.isIdentity()) { + restoreGraphicsState(); + } - if (breakOutList != null) { - restoreStateStackAfterBreakOut(breakOutList); + //For FIXED, we need to restore break out now we are done + if (positioning == Block.FIXED) { + if (breakOutList != null) { + restoreStateStackAfterBreakOut(breakOutList); + } } currentIPPosition = saveIP; @@ -599,8 +622,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { at.translate(0, block.getSpaceBefore()); if (!at.isIdentity()) { - saveGraphicsState(); - concatenateTransformationMatrix(UnitConv.mptToPt(at)); + establishTransformationMatrix(at); } currentIPPosition = 0; @@ -632,8 +654,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { at.translate(currentIPPosition, currentBPPosition); if (!at.isIdentity()) { - saveGraphicsState(); - concatenateTransformationMatrix(UnitConv.mptToPt(at)); + establishTransformationMatrix(at); } currentIPPosition = 0; @@ -845,4 +866,16 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { renderDocument(doc, ns, pos, fo.getForeignAttributes()); } + /** + * Establishes a new coordinate system with the given transformation matrix. + * The current graphics state is saved and the new coordinate system is concatenated. + * @param block + * + * @param at the transformation matrix + */ + protected void establishTransformationMatrix(AffineTransform at) { + saveGraphicsState(); + concatenateTransformationMatrix(UnitConv.mptToPt(at)); + } + } diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index 2be9150b0..943c8c9da 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -29,11 +29,8 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import org.w3c.dom.Document; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.area.Area; @@ -69,6 +66,7 @@ import org.apache.fop.area.inline.WordArea; import org.apache.fop.events.ResourceEventProducer; import org.apache.fop.fo.Constants; import org.apache.fop.fonts.FontInfo; +import org.w3c.dom.Document; /** * Abstract base class for all renderers. The Abstract renderer does all the @@ -505,7 +503,7 @@ public abstract class AbstractRenderer */ protected void renderBlocks(Block parent, List blocks) { int saveIP = currentIPPosition; - int saveBP = currentBPPosition; +// int saveBP = currentBPPosition; // Calculate the position of the content rectangle. if (parent != null && !parent.getTraitAsBoolean(Trait.IS_VIEWPORT_AREA)) { diff --git a/src/java/org/apache/fop/render/ImageHandler.java b/src/java/org/apache/fop/render/ImageHandler.java index 42ae5fd49..ec5f576aa 100644 --- a/src/java/org/apache/fop/render/ImageHandler.java +++ b/src/java/org/apache/fop/render/ImageHandler.java @@ -23,26 +23,11 @@ import java.awt.Rectangle; import java.io.IOException; import org.apache.xmlgraphics.image.loader.Image; -import org.apache.xmlgraphics.image.loader.ImageFlavor; /** - * This interface is used for handling all sorts of image types for PDF output. + * This interface is a service provider interface for image handlers. */ -public interface ImageHandler { - - /** - * Returns the priority for this image handler. A lower value means higher priority. This - * information is used to build the ordered/prioritized list of supported ImageFlavors. - * The built-in handlers use priorities between 100 and 999. - * @return a positive integer (>0) indicating the priority - */ - int getPriority(); - - /** - * Returns the {@link ImageFlavor}s supported by this instance - * @return the supported image flavors - */ - ImageFlavor[] getSupportedImageFlavors(); +public interface ImageHandler extends ImageHandlerBase { /** * Indicates whether the image handler is compatible with the indicated target represented @@ -58,12 +43,6 @@ public interface ImageHandler { boolean isCompatible(RenderingContext targetContext, Image image); /** - * Returns the {@link Image} subclass supported by this instance. - * @return the Image type - */ - Class getSupportedImageClass(); - - /** * Handles the given {@link Image} instance painting it at the indicated position in the * output format being generated. * @param context the rendering context diff --git a/src/java/org/apache/fop/render/ImageHandlerBase.java b/src/java/org/apache/fop/render/ImageHandlerBase.java new file mode 100644 index 000000000..f07c89671 --- /dev/null +++ b/src/java/org/apache/fop/render/ImageHandlerBase.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render; + +import org.apache.xmlgraphics.image.loader.ImageFlavor; + +/** + * This interface is a service provider base interface for image handlers. It only contains + * methods necessary for registration and is extended by sub-interfaces with the actual + * image handling contract. + */ +public interface ImageHandlerBase { + + /** + * Returns the priority for this image handler. A lower value means higher priority. This + * information is used to build the ordered/prioritized list of supported ImageFlavors. + * The built-in handlers use priorities between 100 and 999. + * @return a positive integer (>0) indicating the priority + */ + int getPriority(); + + /** + * Returns the {@link ImageFlavor}s supported by this instance + * @return the supported image flavors + */ + ImageFlavor[] getSupportedImageFlavors(); + + /** + * Returns the {@link Class} subclass supported by this instance. + * @return the image Class type + */ + Class getSupportedImageClass(); +} diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java index 818e31568..76f727e84 100644 --- a/src/java/org/apache/fop/render/PrintRenderer.java +++ b/src/java/org/apache/fop/render/PrintRenderer.java @@ -24,8 +24,6 @@ import java.awt.geom.Rectangle2D; import java.util.List; import java.util.Map; -import org.w3c.dom.Document; - import org.apache.fop.apps.FOPException; import org.apache.fop.area.Area; import org.apache.fop.area.Trait; @@ -37,6 +35,7 @@ import org.apache.fop.fonts.FontManager; import org.apache.fop.fonts.FontResolver; import org.apache.fop.fonts.FontTriplet; import org.apache.fop.fonts.base14.Base14FontCollection; +import org.w3c.dom.Document; /** Abstract base class of "Print" type renderers. */ public abstract class PrintRenderer extends AbstractRenderer { @@ -109,6 +108,14 @@ public abstract class PrintRenderer extends AbstractRenderer { } /** + * Instantiates a RendererContext for an image + * @return a newly created RendererContext. + */ + protected RendererContext instantiateRendererContext() { + return new RendererContext(this, getMimeType()); + } + + /** * Creates a RendererContext for an image. * @param x the x coordinate (in millipoints) * @param y the y coordinate (in millipoints) @@ -119,8 +126,7 @@ public abstract class PrintRenderer extends AbstractRenderer { */ protected RendererContext createRendererContext(int x, int y, int width, int height, Map foreignAttributes) { - RendererContext context; - context = new RendererContext(this, getMimeType()); + RendererContext context = instantiateRendererContext(); context.setUserAgent(userAgent); context.setProperty(RendererContextConstants.WIDTH, diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java index 595bdd7c2..ac885a44b 100644 --- a/src/java/org/apache/fop/render/RendererContext.java +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -20,9 +20,12 @@ package org.apache.fop.render; //Java +import java.util.Iterator; import java.util.Map; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.xmlgraphics.util.QName; /** * The Render Context for external handlers. This provides a rendering context @@ -30,21 +33,28 @@ import org.apache.fop.apps.FOUserAgent; * render target. */ public class RendererContext { + /** conversion-mode extension attribute */ + protected static final QName CONVERSION_MODE = new QName( + ExtensionElementMapping.URI, null, "conversion-mode"); - private String mime; - private AbstractRenderer renderer; + /** "bitmap" value for the "conversion-mode" extension attribute. */ + protected static final String BITMAP = "bitmap"; + + private final String mime; + private final AbstractRenderer renderer; private FOUserAgent userAgent; - private Map props = new java.util.HashMap(); + + private final Map/*<String,Object>*/ props = new java.util.HashMap/*<String,Object>*/(); /** - * Contructor for this class. It takes a MIME type as parameter. + * Constructor for this class. It takes a MIME type as parameter. * - * @param renderer The current renderer - * @param m The MIME type of the output that's generated. + * @param renderer the current renderer + * @param mime the MIME type of the output that's generated. */ - public RendererContext(AbstractRenderer renderer, String m) { + public RendererContext(AbstractRenderer renderer, String mime) { this.renderer = renderer; - this.mime = m; + this.mime = mime; } /** @@ -112,6 +122,19 @@ public class RendererContext { return wrapper; } + /** {@inheritDoc} **/ + public String toString() { + StringBuffer stringBuffer = new StringBuffer("RendererContext{\n"); + Iterator it = props.keySet().iterator(); + while (it.hasNext()) { + String key = (String)it.next(); + Object value = props.get(key); + stringBuffer.append("\t" + key + "=" + value + "\n"); + } + stringBuffer.append("}"); + return stringBuffer.toString(); + } + /** * Base class for a wrapper around RendererContext to access its properties in a type-safe, * renderer-specific way. @@ -158,6 +181,19 @@ public class RendererContext { public Map getForeignAttributes() { return (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); } + + /** {@inheritDoc} */ + public String toString() { + return "RendererContextWrapper{" + + "userAgent=" + getUserAgent() + + "x=" + getCurrentXPosition() + + "y=" + getCurrentYPosition() + + "width=" + getWidth() + + "height=" + getHeight() + + "foreignAttributes=" + getForeignAttributes() + + "}"; + + } } } diff --git a/src/java/org/apache/fop/render/afp/AFPEventProducer.java b/src/java/org/apache/fop/render/afp/AFPEventProducer.java deleted file mode 100644 index 08641b20e..000000000 --- a/src/java/org/apache/fop/render/afp/AFPEventProducer.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import org.apache.fop.events.EventBroadcaster; -import org.apache.fop.events.EventProducer; -import org.apache.fop.events.model.AbstractEventModelFactory; -import org.apache.fop.events.model.EventModel; - -/** - * Event producer interface for AFP-specific events. - */ -public interface AFPEventProducer extends EventProducer { - - /** Provider class for the event producer. */ - class Provider { - - /** - * Returns an event producer. - * @param broadcaster the event broadcaster to use - * @return the event producer - */ - public static AFPEventProducer get(EventBroadcaster broadcaster) { - return (AFPEventProducer)broadcaster.getEventProducerFor( - AFPEventProducer.class); - } - } - - /** Event model factory for AFP. */ - public static class EventModelFactory extends AbstractEventModelFactory { - - /** {@inheritDoc} */ - public EventModel createEventModel() { - return loadModel(getClass(), "event-model.xml"); - } - - } - - /** - * Warn about using default font setup. - * @param source the event source - * @event.severity WARN - */ - void warnDefaultFontSetup(Object source); - -} diff --git a/src/java/org/apache/fop/render/afp/AFPEventProducer.xml b/src/java/org/apache/fop/render/afp/AFPEventProducer.xml index b0eeeb202..23bd9a182 100644 --- a/src/java/org/apache/fop/render/afp/AFPEventProducer.xml +++ b/src/java/org/apache/fop/render/afp/AFPEventProducer.xml @@ -1,3 +1 @@ -<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en"> - <message key="org.apache.fop.render.afp.AFPEventProducer.warnDefaultFontSetup">No AFP fonts configured. Using default setup.</message> -</catalogue> +<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en"/> diff --git a/src/java/org/apache/fop/render/afp/AFPFontAttributes.java b/src/java/org/apache/fop/render/afp/AFPFontAttributes.java deleted file mode 100644 index fb6f82463..000000000 --- a/src/java/org/apache/fop/render/afp/AFPFontAttributes.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp; - -import org.apache.fop.render.afp.fonts.AFPFont; - -/** - * This class encapsulates the font attributes that need to be included - * in the AFP data stream. This class does not assist in converting the - * font attributes to AFP code pages and character set values. - * - */ -public class AFPFontAttributes { - - /** - * The font reference - */ - private int fontReference; - - /** - * The font key - */ - private String fontKey; - - /** - * The font - */ - private AFPFont font; - - /** - * The point size - */ - private int pointSize; - - /** - * Constructor for the AFPFontAttributes - * @param fontKey the font key - * @param font the font - * @param pointSize the point size - */ - public AFPFontAttributes(String fontKey, AFPFont font, int pointSize) { - this.fontKey = fontKey; - this.font = font; - this.pointSize = pointSize; - } - - /** - * @return the font - */ - public AFPFont getFont() { - return font; - } - - /** - * @return the FontKey attribute - */ - public String getFontKey() { - return fontKey + pointSize; - } - - /** - * @return the point size attribute - */ - public int getPointSize() { - return pointSize; - } - - /** - * @return the FontReference attribute - */ - public int getFontReference() { - return fontReference; - } - - /** - * Sets the FontReference attribute - * @param fontReference the FontReference to set - */ - public void setFontReference(int fontReference) { - this.fontReference = fontReference; - } - -} diff --git a/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java new file mode 100644 index 000000000..2b5077fe9 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.io.File; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceLevel; +import org.apache.fop.render.afp.extensions.AFPElementMapping; +import org.apache.xmlgraphics.util.QName; + +/** + * Parses any AFP foreign attributes + */ +public class AFPForeignAttributeReader { + private static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp"); + + /** the resource-name attribute */ + public static final String RESOURCE_NAME = "afp:resource-name"; + + /** the resource-level attribute */ + public static final String RESOURCE_LEVEL = "afp:resource-level"; + + /** the resource-group-file attribute */ + public static final String RESOURCE_GROUP_FILE = "afp:resource-group-file"; + + /** + * Main constructor + */ + public AFPForeignAttributeReader() { + } + + /** + * Returns the resource information + * + * @param foreignAttributes the foreign attributes + * @return the resource information + */ + public AFPResourceInfo getResourceInfo(Map/*<QName, String>*/ foreignAttributes) { + AFPResourceInfo resourceInfo = new AFPResourceInfo(); + if (foreignAttributes != null && !foreignAttributes.isEmpty()) { + QName resourceNameKey = new QName(AFPElementMapping.NAMESPACE, RESOURCE_NAME); + String resourceName = (String)foreignAttributes.get(resourceNameKey); + if (resourceName != null) { + resourceInfo.setName(resourceName); + } + AFPResourceLevel level = getResourceLevel(foreignAttributes); + if (level != null) { + resourceInfo.setLevel(level); + } + } + return resourceInfo; + } + + /** + * Returns the resource level + * + * @param foreignAttributes the foreign attributes + * @return the resource level + */ + public AFPResourceLevel getResourceLevel(Map/*<QName, String>*/ foreignAttributes) { + AFPResourceLevel resourceLevel = null; + if (foreignAttributes != null && !foreignAttributes.isEmpty()) { + QName resourceLevelKey = new QName(AFPElementMapping.NAMESPACE, RESOURCE_LEVEL); + if (foreignAttributes.containsKey(resourceLevelKey)) { + String levelString = (String)foreignAttributes.get(resourceLevelKey); + resourceLevel = AFPResourceLevel.valueOf(levelString); + // if external get resource group file attributes + if (resourceLevel != null && resourceLevel.isExternal()) { + QName resourceGroupFileKey = new QName(AFPElementMapping.NAMESPACE, + RESOURCE_GROUP_FILE); + String resourceGroupFile + = (String)foreignAttributes.get(resourceGroupFileKey); + if (resourceGroupFile == null) { + String msg = RESOURCE_GROUP_FILE + " not specified"; + log.error(msg); + throw new UnsupportedOperationException(msg); + } + File resourceExternalGroupFile = new File(resourceGroupFile); + SecurityManager security = System.getSecurityManager(); + try { + if (security != null) { + security.checkWrite(resourceExternalGroupFile.getPath()); + } + } catch (SecurityException ex) { + String msg = "unable to gain write access to external resource file: " + + resourceGroupFile; + log.error(msg); + } + + try { + boolean exists = resourceExternalGroupFile.exists(); + if (exists) { + log.warn("overwriting external resource file: " + + resourceGroupFile); + } + resourceLevel.setExternalFilePath(resourceGroupFile); + } catch (SecurityException ex) { + String msg = "unable to gain read access to external resource file: " + + resourceGroupFile; + log.error(msg); + } + } + } + } + return resourceLevel; + } +} diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java index 18ac4dbb6..becafda23 100644 --- a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java @@ -19,40 +19,87 @@ package org.apache.fop.render.afp; +import java.awt.Dimension; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - +import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.afp.AFPGraphicsObjectInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceManager; import org.apache.fop.render.AbstractGraphics2DAdapter; import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContext.RendererContextWrapper; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; /** * Graphics2DAdapter implementation for AFP. */ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { + private final AFPPaintingState paintingState; + /** * Main constructor + * + * @param paintingState the AFP painting state */ - public AFPGraphics2DAdapter() { + public AFPGraphics2DAdapter(AFPPaintingState paintingState) { + this.paintingState = paintingState; } /** {@inheritDoc} */ public void paintImage(Graphics2DImagePainter painter, - RendererContext context, + RendererContext rendererContext, int x, int y, int width, int height) throws IOException { - RendererContext.RendererContextWrapper wrappedContext - = new RendererContext.RendererContextWrapper(context); - AFPRenderer afp = (AFPRenderer)context.getRenderer(); - Boolean grayObj = (Boolean)context.getProperty(AFPRendererContextConstants.AFP_GRAYSCALE); - boolean gray = (grayObj != null ? grayObj.booleanValue() : false); - //Paint to a BufferedImage - int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); - BufferedImage bi = paintToBufferedImage(painter, wrappedContext, resolution, gray, false); + AFPRendererContext afpRendererContext = (AFPRendererContext)rendererContext; + AFPInfo afpInfo = afpRendererContext.getInfo(); + + final boolean textAsShapes = false; + AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes); + + paintingState.save(); + + //Fallback solution: Paint to a BufferedImage + if (afpInfo.paintAsBitmap()) { - afp.drawBufferedImage(bi, resolution, x, y, width, height); + // paint image + RendererContextWrapper rendererContextWrapper + = RendererContext.wrapRendererContext(rendererContext); + float targetResolution = rendererContext.getUserAgent().getTargetResolution(); + int resolution = Math.round(targetResolution); + boolean colorImages = afpInfo.isColorSupported(); + BufferedImage bufferedImage = paintToBufferedImage( + painter, rendererContextWrapper, resolution, !colorImages, false); + + // draw image + AffineTransform at = paintingState.getData().getTransform(); + at.translate(x, y); + g2d.drawImage(bufferedImage, at, null); + } else { + AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo(); + graphicsObjectInfo.setPainter(painter); + graphicsObjectInfo.setGraphics2D(g2d); + + // get the 'width' and 'height' attributes of the SVG document + Dimension imageSize = painter.getImageSize(); + float imw = (float)imageSize.getWidth() / 1000f; + float imh = (float)imageSize.getHeight() / 1000f; + + Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); + graphicsObjectInfo.setArea(area); + AFPResourceManager resourceManager = afpInfo.getResourceManager(); + resourceManager.createObject(graphicsObjectInfo); + } + + paintingState.restore(); } + /** {@inheritDoc} */ + protected int mpt2px(int unit, int resolution) { + return Math.round(paintingState.getUnitConverter().mpt2units(unit)); + } } diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandler.java b/src/java/org/apache/fop/render/afp/AFPImageHandler.java new file mode 100644 index 000000000..a6d2d613d --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandler.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.awt.Point; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.Map; + +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPUnitConverter; +import org.apache.fop.render.ImageHandlerBase; + +/** + * A base abstract AFP image handler + */ +public abstract class AFPImageHandler implements ImageHandlerBase { + private static final int X = 0; + private static final int Y = 1; + + /** foreign attribute reader */ + private final AFPForeignAttributeReader foreignAttributeReader + = new AFPForeignAttributeReader(); + + /** + * Generates an intermediate AFPDataObjectInfo that is later used to construct + * the appropriate data object in the AFP DataStream. + * + * @param rendererImageInfo the renderer image info + * @return a data object info object + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + public AFPDataObjectInfo generateDataObjectInfo( + AFPRendererImageInfo rendererImageInfo) throws IOException { + AFPDataObjectInfo dataObjectInfo = createDataObjectInfo(); + + // set resource information + Map foreignAttributes = rendererImageInfo.getForeignAttributes(); + AFPResourceInfo resourceInfo + = foreignAttributeReader.getResourceInfo(foreignAttributes); + resourceInfo.setUri(rendererImageInfo.getURI()); + dataObjectInfo.setResourceInfo(resourceInfo); + + // set object area + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); + + Point origin = rendererImageInfo.getOrigin(); + Rectangle2D position = rendererImageInfo.getPosition(); + float srcX = origin.x + (float)position.getX(); + float srcY = origin.y + (float)position.getY(); + + AFPRendererContext rendererContext + = (AFPRendererContext)rendererImageInfo.getRendererContext(); + AFPInfo afpInfo = rendererContext.getInfo(); + AFPPaintingState paintingState = afpInfo.getPaintingState(); + AFPUnitConverter unitConv = paintingState.getUnitConverter(); + int[] coords = unitConv.mpts2units(new float[] {srcX, srcY}); + objectAreaInfo.setX(coords[X]); + objectAreaInfo.setY(coords[Y]); + + int width = Math.round(unitConv.mpt2units((float)position.getWidth())); + objectAreaInfo.setWidth(width); + + int height = Math.round(unitConv.mpt2units((float)position.getHeight())); + objectAreaInfo.setHeight(height); + + int resolution = paintingState.getResolution(); + objectAreaInfo.setHeightRes(resolution); + objectAreaInfo.setWidthRes(resolution); + + objectAreaInfo.setRotation(paintingState.getRotation()); + + dataObjectInfo.setObjectAreaInfo(objectAreaInfo); + + return dataObjectInfo; + } + + /** + * Creates the data object information object + * + * @return the data object information object + */ + protected abstract AFPDataObjectInfo createDataObjectInfo(); +} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java new file mode 100644 index 000000000..0780e8a59 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.io.IOException; + +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.afp.AFPGraphicsObjectInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceLevel; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; +import org.apache.xmlgraphics.util.MimeConstants; + +/** + * PDFImageHandler implementation which handles Graphics2D images. + */ +public class AFPImageHandlerGraphics2D extends AFPImageHandler { + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.GRAPHICS2D + }; + + /** {@inheritDoc} */ + public AFPDataObjectInfo generateDataObjectInfo( + AFPRendererImageInfo rendererImageInfo) throws IOException { + + AFPRendererContext rendererContext + = (AFPRendererContext)rendererImageInfo.getRendererContext(); + AFPInfo afpInfo = rendererContext.getInfo(); + ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage(); + Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter(); + + if (afpInfo.paintAsBitmap()) { + int x = afpInfo.getX(); + int y = afpInfo.getY(); + int width = afpInfo.getWidth(); + int height = afpInfo.getHeight(); + AFPPaintingState paintingState = afpInfo.getPaintingState(); + AFPGraphics2DAdapter g2dAdapter = new AFPGraphics2DAdapter(paintingState); + g2dAdapter.paintImage(painter, rendererContext, x, y, width, height); + return null; + } else { + AFPGraphicsObjectInfo graphicsObjectInfo + = (AFPGraphicsObjectInfo)super.generateDataObjectInfo(rendererImageInfo); + + AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo(); + //level not explicitly set/changed so default to inline for GOCA graphic objects + // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine) + if (!resourceInfo.levelChanged()) { + resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); + } + + // set mime type (unsupported by MOD:CA registry) + graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA); + + // set g2d + boolean textAsShapes = false; + + AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes); + + graphicsObjectInfo.setGraphics2D(g2d); + + // set painter + graphicsObjectInfo.setPainter(painter); + + return graphicsObjectInfo; + } + } + + /** {@inheritDoc} */ + public int getPriority() { + return 200; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageGraphics2D.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return FLAVORS; + } + + /** {@inheritDoc} */ + protected AFPDataObjectInfo createDataObjectInfo() { + return new AFPGraphicsObjectInfo(); + } +} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java new file mode 100644 index 000000000..3ac1d5696 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.io.IOException; + +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPImageObjectInfo; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; + +/** + * AFPImageHandler implementation which handles CCITT encoded images (CCITT fax group 3/4). + */ +public class AFPImageHandlerRawCCITTFax extends AbstractAFPImageHandlerRawStream { + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.RAW_CCITTFAX, + }; + + /** {@inheritDoc} */ + public AFPDataObjectInfo generateDataObjectInfo( + AFPRendererImageInfo rendererImageInfo) throws IOException { + AFPImageObjectInfo imageObjectInfo + = (AFPImageObjectInfo)super.generateDataObjectInfo(rendererImageInfo); + + ImageRawCCITTFax ccitt = (ImageRawCCITTFax) rendererImageInfo.getImage(); + int compression = ccitt.getCompression(); + imageObjectInfo.setCompression(compression); + + imageObjectInfo.setBitsPerPixel(1); + return imageObjectInfo; + } + + /** {@inheritDoc} */ + protected AFPDataObjectInfo createDataObjectInfo() { + return new AFPImageObjectInfo(); + } + + /** {@inheritDoc} */ + public int getPriority() { + return 400; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageRawCCITTFax.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return FLAVORS; + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java new file mode 100644 index 000000000..ded9ec9d5 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; + +/** + * AFPImageHandler implementation which handles raw stream images. + */ +public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream { + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.RAW_JPEG, + ImageFlavor.RAW_EPS, + }; + + /** {@inheritDoc} */ + public int getPriority() { + return 200; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageRawStream.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return FLAVORS; + } + + /** {@inheritDoc} */ + protected AFPDataObjectInfo createDataObjectInfo() { + return new AFPDataObjectInfo(); + } +} diff --git a/src/java/org/apache/fop/render/afp/modca/MaximumSizeExceededException.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java index a66fa9b30..59ca6cf38 100644 --- a/src/java/org/apache/fop/render/afp/modca/MaximumSizeExceededException.java +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java @@ -17,21 +17,26 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp; + +import org.apache.fop.render.AbstractImageHandlerRegistry; /** - * An exception to handle maximum sizes being exceeded. - * + * This class holds references to various image handlers used by the AFP renderer. It also + * supports automatic discovery of additional handlers available through + * the class path. */ -public class MaximumSizeExceededException extends Exception { - - private static final long serialVersionUID = 7823120005542216446L; +public class AFPImageHandlerRegistry extends AbstractImageHandlerRegistry { /** - * Default constructor + * Main constructor */ - public MaximumSizeExceededException() { - super(); + public AFPImageHandlerRegistry() { + } + + /** {@inheritDoc} */ + public Class getHandlerClass() { + return AFPImageHandler.class; } } diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java new file mode 100644 index 000000000..28c942a08 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.awt.image.RenderedImage; +import java.io.IOException; + +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPImageObjectInfo; +import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageRendered; +import org.apache.xmlgraphics.ps.ImageEncodingHelper; +import org.apache.xmlgraphics.util.MimeConstants; + +/** + * PDFImageHandler implementation which handles RenderedImage instances. + */ +public class AFPImageHandlerRenderedImage extends AFPImageHandler { + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.BUFFERED_IMAGE, + ImageFlavor.RENDERED_IMAGE + }; + + /** {@inheritDoc} */ + public AFPDataObjectInfo generateDataObjectInfo( + AFPRendererImageInfo rendererImageInfo) throws IOException { + AFPImageObjectInfo imageObjectInfo + = (AFPImageObjectInfo)super.generateDataObjectInfo(rendererImageInfo); + + AFPRendererContext rendererContext + = (AFPRendererContext)rendererImageInfo.getRendererContext(); + AFPInfo afpInfo = rendererContext.getInfo(); + AFPPaintingState paintingState = afpInfo.getPaintingState(); + int resolution = paintingState.getResolution(); + + imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45); + imageObjectInfo.setDataHeightRes(resolution); + imageObjectInfo.setDataWidthRes(resolution); + + ImageRendered imageRendered = (ImageRendered) rendererImageInfo.img; + RenderedImage renderedImage = imageRendered.getRenderedImage(); + + int dataHeight = renderedImage.getHeight(); + imageObjectInfo.setDataHeight(dataHeight); + + int dataWidth = renderedImage.getWidth(); + imageObjectInfo.setDataWidth(dataWidth); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos); + byte[] imageData = baos.toByteArray(); + + boolean colorImages = paintingState.isColorImages(); + imageObjectInfo.setColor(colorImages); + + // convert to grayscale + if (!colorImages) { + baos.reset(); + int bitsPerPixel = paintingState.getBitsPerPixel(); + imageObjectInfo.setBitsPerPixel(bitsPerPixel); + ImageEncodingHelper.encodeRGBAsGrayScale( + imageData, dataWidth, dataHeight, bitsPerPixel, baos); + imageData = baos.toByteArray(); + } + imageObjectInfo.setData(imageData); + + // set object area info + AFPObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo(); + objectAreaInfo.setWidthRes(resolution); + objectAreaInfo.setHeightRes(resolution); + + return imageObjectInfo; + } + + /** {@inheritDoc} */ + protected AFPDataObjectInfo createDataObjectInfo() { + return new AFPImageObjectInfo(); + } + + /** {@inheritDoc} */ + public int getPriority() { + return 300; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageRendered.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return FLAVORS; + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java new file mode 100644 index 000000000..7ea1a7a10 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.util.Map; + +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContextConstants; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; +import org.w3c.dom.Document; + +/** + * PDFImageHandler implementation which handles XML-based images. + */ +public class AFPImageHandlerXML extends AFPImageHandler { + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.XML_DOM, + }; + + /** {@inheritDoc} */ + public AFPDataObjectInfo generateDataObjectInfo(AFPRendererImageInfo rendererImageInfo) + throws IOException { + RendererContext rendererContext = rendererImageInfo.getRendererContext(); + AFPRenderer renderer = (AFPRenderer)rendererContext.getRenderer(); + ImageXMLDOM imgXML = (ImageXMLDOM)rendererImageInfo.getImage(); + Document doc = imgXML.getDocument(); + String ns = imgXML.getRootNamespace(); + Map foreignAttributes = (Map)rendererContext.getProperty( + RendererContextConstants.FOREIGN_ATTRIBUTES); + Rectangle2D pos = rendererImageInfo.getPosition(); + renderer.renderDocument(doc, ns, pos, foreignAttributes); + return null; + } + + /** {@inheritDoc} */ + public int getPriority() { + return 400; + } + + /** {@inheritDoc} */ + public Class getSupportedImageClass() { + return ImageXMLDOM.class; + } + + /** {@inheritDoc} */ + public ImageFlavor[] getSupportedImageFlavors() { + return FLAVORS; + } + + /** {@inheritDoc} */ + protected AFPDataObjectInfo createDataObjectInfo() { + return null; + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPInfo.java b/src/java/org/apache/fop/render/afp/AFPInfo.java new file mode 100644 index 000000000..fb1ec87a8 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPInfo.java @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.fonts.FontInfo; + +/** + * AFP information structure for drawing the XML document. + */ +public final class AFPInfo { + /** see WIDTH */ + private int width; + + /** see HEIGHT */ + private int height; + + /** see XPOS */ + private int x; + + /** see YPOS */ + private int y; + + /** see HANDLER_CONFIGURATION */ + private Configuration handlerConfiguration; + + /** see AFP_FONT_INFO */ + private FontInfo fontInfo; + + /** See AFP_PAINTING_STATE */ + private AFPPaintingState paintingState; + + /** See AFP_RESOURCE_MANAGER */ + private AFPResourceManager resourceManager; + + /** See AFP_RESOURCE_INFO */ + private AFPResourceInfo resourceInfo; + + /** true if SVG should be rendered as a bitmap instead of natively */ + private boolean paintAsBitmap; + + /** + * Returns the width. + * + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * Sets the width. + * + * @param width The pageWidth to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * Returns the height. + * + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * + * @param height The height to set + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * Returns the handler configuration + * + * @return the handler configuration + */ + public Configuration getHandlerConfiguration() { + return this.handlerConfiguration; + } + + /** + * Sets the handler configuration + * + * @param cfg the handler configuration + */ + public void setHandlerConfiguration(Configuration cfg) { + this.handlerConfiguration = cfg; + } + + /** + * Return the font info + * + * @return the font info + */ + public FontInfo getFontInfo() { + return this.fontInfo; + } + + /** + * Returns the current AFP state + * + * @return the current AFP state + */ + public AFPPaintingState getPaintingState() { + return this.paintingState; + } + + /** + * Returns the AFPResourceManager + * + * @return the AFPResourceManager + */ + public AFPResourceManager getResourceManager() { + return this.resourceManager; + } + + /** + * Returns true if supports color + * + * @return true if supports color + */ + public boolean isColorSupported() { + return getPaintingState().isColorImages(); + } + + /** + * Returns the current x position coordinate + * + * @return the current x position coordinate + */ + protected int getX() { + return x; + } + + /** + * Returns the current y position coordinate + * + * @return the current y position coordinate + */ + protected int getY() { + return y; + } + + /** + * Returns the resolution + * + * @return the resolution + */ + protected int getResolution() { + return getPaintingState().getResolution(); + } + + /** + * Returns the number of bits per pixel to use + * @return the number of bits per pixel to use + */ + protected int getBitsPerPixel() { + return getPaintingState().getBitsPerPixel(); + } + + /** + * Sets the current x position coordinate + * + * @param x the current x position coordinate + */ + protected void setX(int x) { + this.x = x; + } + + /** + * Sets the current y position coordinate + * + * @param y the current y position coordinate + */ + protected void setY(int y) { + this.y = y; + } + + /** + * Sets the current font info + * + * @param fontInfo the current font info + */ + protected void setFontInfo(FontInfo fontInfo) { + this.fontInfo = fontInfo; + } + + /** + * Sets the AFP state + * + * @param paintingState the AFP state + */ + public void setPaintingState(AFPPaintingState paintingState) { + this.paintingState = paintingState; + } + + /** + * Sets the AFPResourceManager + * + * @param resourceManager the AFPResourceManager + */ + public void setResourceManager(AFPResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + /** + * Sets true if SVG should be rendered as a bitmap instead of natively + * + * @param b boolean value + */ + public void setPaintAsBitmap(boolean b) { + this.paintAsBitmap = b; + } + + /** + * Returns true if SVG should be rendered as a bitmap instead of natively + * + * @return true if SVG should be rendered as a bitmap instead of natively + */ + public boolean paintAsBitmap() { + return this.paintAsBitmap; + } + + /** + * Returns true if text should be stroked when painted + * + * @return true if text should be stroked when painted + */ + public boolean strokeText() { + boolean strokeText = false; + if (handlerConfiguration != null) { + strokeText = handlerConfiguration.getChild("stroke-text", true).getValueAsBoolean(strokeText); + } + return strokeText; + } + + /** + * Sets the resource information + * + * @param resourceInfo the resource information + */ + public void setResourceInfo(AFPResourceInfo resourceInfo) { + this.resourceInfo = resourceInfo; + } + + /** + * Returns the resource information + * + * @return the resource information + */ + public AFPResourceInfo getResourceInfo() { + return resourceInfo; + } + + /** + * Creates an AFPGraphics2D implementation + * + * @param textAsShapes true when text is painted as shapes + * @return a newly created AFPGraphics2D + */ + public AFPGraphics2D createGraphics2D(boolean textAsShapes) { + AFPGraphics2D g2d = new AFPGraphics2D( + textAsShapes, paintingState, resourceManager, resourceInfo, fontInfo); + g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + return g2d; + } + + /** {@inheritDoc} */ + public String toString() { + return "AFPInfo{width=" + width + + ", height=" + height + + ", x=" + x + + ", y=" + y + + ", cfg=" + handlerConfiguration + + ", fontInfo=" + fontInfo + + ", resourceManager=" + resourceManager + + ", paintingState=" + paintingState + + ", paintAsBitmap=" + paintAsBitmap + + ", resourceInfo=" + resourceInfo + + "}"; + } + +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index d5129f167..8035a9490 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -23,56 +23,46 @@ import java.awt.Color; import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.RenderedImage; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.output.ByteArrayOutputStream; - -import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; -import org.apache.xmlgraphics.image.loader.ImageException; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.image.loader.ImageInfo; -import org.apache.xmlgraphics.image.loader.ImageManager; -import org.apache.xmlgraphics.image.loader.ImageSessionContext; -import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D; -import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; -import org.apache.xmlgraphics.image.loader.impl.ImageRendered; -import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; -import org.apache.xmlgraphics.image.loader.util.ImageUtil; -import org.apache.xmlgraphics.ps.ImageEncodingHelper; - +import org.apache.fop.afp.AFPBorderPainter; +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPEventProducer; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPRectanglePainter; +import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.afp.AFPTextDataInfo; +import org.apache.fop.afp.AFPUnitConverter; +import org.apache.fop.afp.BorderPaintingInfo; +import org.apache.fop.afp.DataStream; +import org.apache.fop.afp.RectanglePaintingInfo; +import org.apache.fop.afp.fonts.AFPFont; +import org.apache.fop.afp.fonts.AFPFontAttributes; +import org.apache.fop.afp.fonts.AFPFontCollection; +import org.apache.fop.afp.fonts.AFPPageFonts; +import org.apache.fop.afp.fonts.CharacterSet; +import org.apache.fop.afp.modca.PageObject; +import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; -import org.apache.fop.area.Block; -import org.apache.fop.area.BlockViewport; -import org.apache.fop.area.BodyRegion; import org.apache.fop.area.CTM; -import org.apache.fop.area.NormalFlow; +import org.apache.fop.area.LineArea; import org.apache.fop.area.OffDocumentItem; import org.apache.fop.area.PageViewport; -import org.apache.fop.area.RegionReference; -import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.Leader; -import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.area.inline.TextArea; -import org.apache.fop.area.inline.WordArea; import org.apache.fop.datatypes.URISpecification; import org.apache.fop.events.ResourceEventProducer; -import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExtensionAttachment; import org.apache.fop.fonts.FontCollection; import org.apache.fop.fonts.FontInfo; @@ -82,13 +72,13 @@ import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.render.afp.extensions.AFPElementMapping; import org.apache.fop.render.afp.extensions.AFPPageSetup; -import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.fonts.AFPFontCollection; -import org.apache.fop.render.afp.modca.AFPConstants; -import org.apache.fop.render.afp.modca.AFPDataStream; -import org.apache.fop.render.afp.modca.ImageObject; -import org.apache.fop.render.afp.modca.PageObject; -import org.apache.fop.util.ColorUtil; +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; +import org.apache.xmlgraphics.image.loader.util.ImageUtil; +import org.apache.xmlgraphics.ps.ImageEncodingHelper; /** * This is an implementation of a FOP Renderer that renders areas to AFP. @@ -139,140 +129,55 @@ import org.apache.fop.util.ColorUtil; * rectangles. * </p> * - * Note: There are specific extensions that have been added to the - * FO. They are specific to their location within the FO and have to be - * processed accordingly (ie. at the start or end of the page). + * Note: There are specific extensions that have been added to the FO. They are + * specific to their location within the FO and have to be processed accordingly + * (ie. at the start or end of the page). * */ public class AFPRenderer extends AbstractPathOrientedRenderer { - /** - * The default afp renderer output resolution - */ - private static final int DEFAULT_DPI_RESOLUTION = 240; - - /** - * The afp factor for calculating resolutions (e.g. 72000/240 = 300) - */ - private static final int DPI_CONVERSION_FACTOR = 72000; - - /** - * The afp data stream object responsible for generating afp data - */ - private AFPDataStream afpDataStream = null; + private static final int X = 0; + private static final int Y = 1; - /** - * The map of afp root extensions - */ - // UNUSED - // private HashMap rootExtensionMap = null; - /** - * The map of page segments - */ - private HashMap pageSegmentsMap = null; + /** the resource manager */ + private AFPResourceManager resourceManager; - /** - * The fonts on the current page - */ - private HashMap currentPageFonts = null; + /** the painting state */ + private final AFPPaintingState paintingState; - /** - * The current color object - */ - private Color currentColor = null; + /** unit converter */ + private final AFPUnitConverter unitConv; - /** - * The page font number counter, used to determine the next font reference - */ - private int pageFontCounter = 0; + /** the line painter */ + private AFPBorderPainter borderPainter; - /** - * The current font family - */ - // UNUSED - // private String currentFontFamily = ""; - /** - * The current font size - */ - private int currentFontSize = 0; + /** the map of page segments */ + private final Map/*<String,String>*/pageSegmentMap + = new java.util.HashMap/*<String,String>*/(); - /** - * The Options to be set on the AFPRenderer - */ - // UNUSED - // private Map afpOptions = null; - /** - * The page width - */ - private int pageWidth = 0; + /** the map of saved incomplete pages */ + private final Map pages = new java.util.HashMap/*<PageViewport,PageObject>*/(); - /** - * The page height - */ - private int pageHeight = 0; + /** the AFP datastream */ + private DataStream dataStream; - /** - * The current page sequence id - */ - // UNUSED - // private String pageSequenceId = null; - /** - * The portrait rotation - */ - private int portraitRotation = 0; + /** the image handler registry */ + private final AFPImageHandlerRegistry imageHandlerRegistry; - /** - * The landscape rotation - */ - private int landscapeRotation = 270; - - /** - * The line cache, avoids drawing duplicate lines in tables. - */ - // UNUSED - // private HashSet lineCache = null; - /** - * The current x position for line drawing - */ - // UNUSED - // private float x; - /** - * The current y position for line drawing - */ - // UNUSED - // private float y; - /** - * The map of saved incomplete pages - */ - private Map pages = null; - - /** - * Flag to the set the output object type for images - */ - private boolean colorImages = false; - - /** - * Default value for image depth - */ - private int bitsPerPixel = 8; - - /** - * The output resolution - */ - private int resolution = DEFAULT_DPI_RESOLUTION; + private AFPRectanglePainter rectanglePainter; /** * Constructor for AFPRenderer. */ public AFPRenderer() { super(); + this.imageHandlerRegistry = new AFPImageHandlerRegistry(); + this.resourceManager = new AFPResourceManager(); + this.paintingState = new AFPPaintingState(); + this.unitConv = paintingState.getUnitConverter(); } - /** - * Set up the font info - * - * @param inFontInfo font info to set up - */ + /** {@inheritDoc} */ public void setupFontInfo(FontInfo inFontInfo) { this.fontInfo = inFontInfo; FontManager fontManager = userAgent.getFactory().getFontManager(); @@ -282,885 +187,272 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { fontManager.setup(getFontInfo(), fontCollections); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void setUserAgent(FOUserAgent agent) { super.setUserAgent(agent); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void startRenderer(OutputStream outputStream) throws IOException { - currentPageFonts = new HashMap(); - currentColor = new Color(255, 255, 255); - afpDataStream = new AFPDataStream(); - afpDataStream.setPortraitRotation(portraitRotation); - afpDataStream.setLandscapeRotation(landscapeRotation); - afpDataStream.startDocument(outputStream); + paintingState.setColor(Color.WHITE); + + this.dataStream = resourceManager.createDataStream(paintingState, outputStream); + this.borderPainter = new AFPBorderPainter(paintingState, dataStream); + this.rectanglePainter = new AFPRectanglePainter(paintingState, dataStream); + + dataStream.startDocument(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void stopRenderer() throws IOException { - afpDataStream.endDocument(); + dataStream.endDocument(); + resourceManager.writeToStream(); + resourceManager = null; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ + public void startPageSequence(LineArea seqTitle) { + try { + dataStream.startPageGroup(); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + /** {@inheritDoc} */ public boolean supportsOutOfOrder() { - //return false; - return true; + return false; } - /** - * Prepare a page for rendering. This is called if the renderer supports - * out of order rendering. The renderer should prepare the page so that a - * page further on in the set of pages can be rendered. The body of the - * page should not be rendered. The page will be rendered at a later time - * by the call to render page. - * - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void preparePage(PageViewport page) { - // initializeRootExtensions(page); - - // this.currentFontFamily = ""; - this.currentFontSize = 0; - this.pageFontCounter = 0; - this.currentPageFonts.clear(); - // this.lineCache = new HashSet(); - - Rectangle2D bounds = page.getViewArea(); - - this.pageWidth = mpts2units(bounds.getWidth()); - this.pageHeight = mpts2units(bounds.getHeight()); - - // renderPageGroupExtensions(page); - - final int pageRotation = 0; - this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation, - getResolution(), getResolution()); + int pageRotation = paintingState.getPageRotation(); + int pageWidth = paintingState.getPageWidth(); + int pageHeight = paintingState.getPageHeight(); + int resolution = paintingState.getResolution(); + dataStream.startPage(pageWidth, pageHeight, pageRotation, + resolution, resolution); renderPageObjectExtensions(page); - if (this.pages == null) { - this.pages = new HashMap(); - } - this.pages.put(page, afpDataStream.savePage()); - + PageObject currentPage = dataStream.savePage(); + pages.put(page, currentPage); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void processOffDocumentItem(OffDocumentItem odi) { // TODO + log.debug("NYI processOffDocumentItem(" + odi + ")"); } /** {@inheritDoc} */ public Graphics2DAdapter getGraphics2DAdapter() { - return new AFPGraphics2DAdapter(); + return new AFPGraphics2DAdapter(paintingState); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void startVParea(CTM ctm, Rectangle2D clippingRect) { - // dummy not used - } - - /** - * {@inheritDoc} - */ - public void endVParea() { - // dummy not used - } - - /** - * Renders a region viewport. <p> - * - * The region may clip the area and it establishes a position from where - * the region is placed.</p> - * - * @param port The region viewport to be rendered - */ - public void renderRegionViewport(RegionViewport port) { - if (port != null) { - Rectangle2D view = port.getViewArea(); - // The CTM will transform coordinates relative to - // this region-reference area into page coords, so - // set origin for the region to 0,0. - currentBPPosition = 0; - currentIPPosition = 0; - - RegionReference regionReference = port.getRegionReference(); - handleRegionTraits(port); - - /* - _afpDataStream.startOverlay(mpts2units(view.getX()) - , mpts2units(view.getY()) - , mpts2units(view.getWidth()) - , mpts2units(view.getHeight()) - , rotation); - */ - - pushViewPortPos(new ViewPortPos(view, regionReference.getCTM())); - - if (regionReference.getRegionClass() == FO_REGION_BODY) { - renderBodyRegion((BodyRegion) regionReference); - } else { - renderRegion(regionReference); - } - /* - _afpDataStream.endOverlay(); - */ - popViewPortPos(); + saveGraphicsState(); + if (ctm != null) { + AffineTransform at = ctm.toAffineTransform(); + concatenateTransformationMatrix(at); } - } - - /** {@inheritDoc} */ - protected void renderBlockViewport(BlockViewport bv, List children) { - // clip and position viewport if necessary - - // save positions - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - CTM ctm = bv.getCTM(); - int borderPaddingStart = bv.getBorderAndPaddingWidthStart(); - int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore(); - //This is the content-rect - float width = (float)bv.getIPD() / 1000f; - float height = (float)bv.getBPD() / 1000f; - - if (bv.getPositioning() == Block.ABSOLUTE - || bv.getPositioning() == Block.FIXED) { - - //For FIXED, we need to break out of the current viewports to the - //one established by the page. We save the state stack for restoration - //after the block-container has been painted. See below. - List breakOutList = null; - if (bv.getPositioning() == Block.FIXED) { - breakOutList = breakOutOfStateStack(); - } - - AffineTransform positionTransform = new AffineTransform(); - positionTransform.translate(bv.getXOffset(), bv.getYOffset()); - - //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle - positionTransform.translate(-borderPaddingStart, -borderPaddingBefore); - - //skipping fox:transform here - - //saveGraphicsState(); - //Viewport position - //concatenateTransformationMatrix(mptToPt(positionTransform)); - - //Background and borders - float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f; - float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f; - Point2D ptSrc = new Point(0, 0); - Point2D ptDst = positionTransform.transform(ptSrc, null); - Rectangle2D borderRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(), - 1000 * (width + bpwidth), 1000 * (height + bpheight)); - pushViewPortPos(new ViewPortPos(borderRect, new CTM(positionTransform))); - drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight); - - //Shift to content rectangle after border painting - AffineTransform contentRectTransform = new AffineTransform(); - contentRectTransform.translate(borderPaddingStart, borderPaddingBefore); - //concatenateTransformationMatrix(mptToPt(contentRectTransform)); - ptSrc = new Point(0, 0); - ptDst = contentRectTransform.transform(ptSrc, null); - Rectangle2D contentRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(), - 1000 * width, 1000 * height); - pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentRectTransform))); - - //Clipping is not supported, yet - //Rectangle2D clippingRect = null; - //clippingRect = new Rectangle(0, 0, bv.getIPD(), bv.getBPD()); - - //saveGraphicsState(); - //Set up coordinate system for content rectangle - AffineTransform contentTransform = ctm.toAffineTransform(); - //concatenateTransformationMatrix(mptToPt(contentTransform)); - contentRect = new Rectangle2D.Double(0, 0, 1000 * width, 1000 * height); - pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentTransform))); - - currentIPPosition = 0; - currentBPPosition = 0; - renderBlocks(bv, children); - - popViewPortPos(); - popViewPortPos(); - //restoreGraphicsState(); - popViewPortPos(); - //restoreGraphicsState(); - - if (breakOutList != null) { - restoreStateStackAfterBreakOut(breakOutList); - } - - currentIPPosition = saveIP; - currentBPPosition = saveBP; - } else { - - currentBPPosition += bv.getSpaceBefore(); - - //borders and background in the old coordinate system - handleBlockTraits(bv); - - //Advance to start of content area - currentIPPosition += bv.getStartIndent(); - - CTM tempctm = new CTM(containingIPPosition, currentBPPosition); - ctm = tempctm.multiply(ctm); - - //Now adjust for border/padding - currentBPPosition += borderPaddingBefore; - - Rectangle2D clippingRect = null; - clippingRect = new Rectangle(currentIPPosition, currentBPPosition, - bv.getIPD(), bv.getBPD()); - - //startVParea(ctm, clippingRect); - pushViewPortPos(new ViewPortPos(clippingRect, ctm)); - - currentIPPosition = 0; - currentBPPosition = 0; - renderBlocks(bv, children); - //endVParea(); - popViewPortPos(); - - currentIPPosition = saveIP; - currentBPPosition = saveBP; - - currentBPPosition += (int)(bv.getAllocBPD()); + if (clippingRect != null) { + clipRect((float)clippingRect.getX() / 1000f, + (float)clippingRect.getY() / 1000f, + (float)clippingRect.getWidth() / 1000f, + (float)clippingRect.getHeight() / 1000f); } } /** {@inheritDoc} */ - protected void renderReferenceArea(Block block) { - //TODO Remove this method once concatenateTransformationMatrix() is implemented - - // save position and offset - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - //Establish a new coordinate system - AffineTransform at = new AffineTransform(); - at.translate(currentIPPosition, currentBPPosition); - at.translate(block.getXOffset(), block.getYOffset()); - at.translate(0, block.getSpaceBefore()); - - if (!at.isIdentity()) { - Rectangle2D contentRect - = new Rectangle2D.Double(at.getTranslateX(), at.getTranslateY(), - block.getAllocIPD(), block.getAllocBPD()); - pushViewPortPos(new ViewPortPos(contentRect, new CTM(at))); - } - - currentIPPosition = 0; - currentBPPosition = 0; - handleBlockTraits(block); - - List children = block.getChildAreas(); - if (children != null) { - renderBlocks(block, children); - } - - if (!at.isIdentity()) { - popViewPortPos(); - } - - // stacked and relative blocks effect stacking - currentIPPosition = saveIP; - currentBPPosition = saveBP; + public void endVParea() { + restoreGraphicsState(); } /** {@inheritDoc} */ - protected void renderFlow(NormalFlow flow) { - // save position and offset - int saveIP = currentIPPosition; - int saveBP = currentBPPosition; - - //Establish a new coordinate system - AffineTransform at = new AffineTransform(); - at.translate(currentIPPosition, currentBPPosition); - - if (!at.isIdentity()) { - Rectangle2D contentRect - = new Rectangle2D.Double(at.getTranslateX(), at.getTranslateY(), - flow.getAllocIPD(), flow.getAllocBPD()); - pushViewPortPos(new ViewPortPos(contentRect, new CTM(at))); - } - - currentIPPosition = 0; - currentBPPosition = 0; - super.renderFlow(flow); - + protected void concatenateTransformationMatrix(AffineTransform at) { if (!at.isIdentity()) { - popViewPortPos(); + paintingState.concatenate(at); } - - // stacked and relative blocks effect stacking - currentIPPosition = saveIP; - currentBPPosition = saveBP; - } - - - /** {@inheritDoc} */ - protected void concatenateTransformationMatrix(AffineTransform at) { - //Not used here since AFPRenderer defines its own renderBlockViewport() method. - throw new UnsupportedOperationException("NYI"); } /** - * {@inheritDoc} + * Returns the base AFP transform + * + * @return the base AFP transform */ - public void renderPage(PageViewport pageViewport) { - - // initializeRootExtensions(page); + private AffineTransform getBaseTransform() { + AffineTransform baseTransform = new AffineTransform(); + double scale = unitConv.mpt2units(1); + baseTransform.scale(scale, scale); + return baseTransform; + } - // this.currentFontFamily = ""; - this.currentFontSize = 0; - this.pageFontCounter = 0; - this.currentPageFonts.clear(); - // this.lineCache = new HashSet(); + /** {@inheritDoc} */ + public void renderPage(PageViewport pageViewport) throws IOException, FOPException { + paintingState.clear(); Rectangle2D bounds = pageViewport.getViewArea(); - this.pageWidth = mpts2units(bounds.getWidth()); - this.pageHeight = mpts2units(bounds.getHeight()); - - if (pages != null && pages.containsKey(pageViewport)) { - - this.afpDataStream.restorePage((PageObject) pages.remove(pageViewport)); + AffineTransform baseTransform = getBaseTransform(); + paintingState.concatenate(baseTransform); + if (pages.containsKey(pageViewport)) { + dataStream.restorePage( + (PageObject)pages.remove(pageViewport)); } else { - // renderPageGroupExtensions(page); - - final int pageRotation = 0; - this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation, - getResolution(), getResolution()); - - renderPageObjectExtensions(pageViewport); - - } - - pushViewPortPos(new ViewPortPos()); + int pageWidth + = Math.round(unitConv.mpt2units((float)bounds.getWidth())); + paintingState.setPageWidth(pageWidth); - renderPageAreas(pageViewport.getPage()); + int pageHeight + = Math.round(unitConv.mpt2units((float)bounds.getHeight())); + paintingState.setPageHeight(pageHeight); - Iterator i = currentPageFonts.values().iterator(); - while (i.hasNext()) { - AFPFontAttributes afpFontAttributes = (AFPFontAttributes) i.next(); + int pageRotation = paintingState.getPageRotation(); - afpDataStream.createFont( - (byte)afpFontAttributes.getFontReference(), - afpFontAttributes.getFont(), - afpFontAttributes.getPointSize()); + int resolution = paintingState.getResolution(); - } + dataStream.startPage(pageWidth, pageHeight, pageRotation, + resolution, resolution); - try { - afpDataStream.endPage(); - } catch (IOException ioex) { - // TODO What shall we do? + renderPageObjectExtensions(pageViewport); } - popViewPortPos(); - - } - - /** - * {@inheritDoc} - */ - public void clip() { - // TODO - } + super.renderPage(pageViewport); - /** - * {@inheritDoc} - */ - public void clipRect(float x, float y, float width, float height) { - // TODO - } + AFPPageFonts pageFonts = paintingState.getPageFonts(); + if (pageFonts != null && !pageFonts.isEmpty()) { + dataStream.addFontsToCurrentPage(pageFonts); + } - /** - * {@inheritDoc} - */ - public void moveTo(float x, float y) { - // TODO + dataStream.endPage(); } - /** - * {@inheritDoc} - */ - public void lineTo(float x, float y) { - // TODO - } - - /** - * {@inheritDoc} - */ - public void closePath() { - // TODO + /** {@inheritDoc} */ + public void drawBorderLine(float x1, float y1, float x2, float y2, + boolean horz, boolean startOrBefore, int style, Color col) { + BorderPaintingInfo borderPaintInfo = new BorderPaintingInfo(x1, y1, x2, y2, horz, style, col); + borderPainter.paint(borderPaintInfo); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void fillRect(float x, float y, float width, float height) { - /* - afpDataStream.createShading( - pts2units(x), - pts2units(y), - pts2units(width), - pts2units(height), - currentColor.getRed(), - currentColor.getGreen(), - currentColor.getBlue()); - */ - afpDataStream.createLine( - pts2units(x), - pts2units(y), - pts2units(x + width), - pts2units(y), - pts2units(height), - currentColor); + RectanglePaintingInfo rectanglePaintInfo = new RectanglePaintingInfo(x, y, width, height); + rectanglePainter.paint(rectanglePaintInfo); } - /** - * {@inheritDoc} - */ - public void drawBorderLine(float x1, float y1, float x2, float y2, - boolean horz, boolean startOrBefore, int style, Color col) { - float w = x2 - x1; - float h = y2 - y1; - if ((w < 0) || (h < 0)) { - log.error("Negative extent received. Border won't be painted."); - return; - } - switch (style) { - case Constants.EN_DOUBLE: - if (horz) { - float h3 = h / 3; - float ym1 = y1; - float ym2 = ym1 + h3 + h3; - afpDataStream.createLine( - pts2units(x1), - pts2units(ym1), - pts2units(x2), - pts2units(ym1), - pts2units(h3), - col - ); - afpDataStream.createLine( - pts2units(x1), - pts2units(ym2), - pts2units(x2), - pts2units(ym2), - pts2units(h3), - col - ); - } else { - float w3 = w / 3; - float xm1 = x1; - float xm2 = xm1 + w3 + w3; - afpDataStream.createLine( - pts2units(xm1), - pts2units(y1), - pts2units(xm1), - pts2units(y2), - pts2units(w3), - col - ); - afpDataStream.createLine( - pts2units(xm2), - pts2units(y1), - pts2units(xm2), - pts2units(y2), - pts2units(w3), - col - ); - } - break; - case Constants.EN_DASHED: - if (horz) { - float w2 = 2 * h; - while (x1 + w2 < x2) { - afpDataStream.createLine( - pts2units(x1), - pts2units(y1), - pts2units(x1 + w2), - pts2units(y1), - pts2units(h), - col - ); - x1 += 2 * w2; - } - } else { - float h2 = 2 * w; - while (y1 + h2 < y2) { - afpDataStream.createLine( - pts2units(x1), - pts2units(y1), - pts2units(x1), - pts2units(y1 + h2), - pts2units(w), - col - ); - y1 += 2 * h2; - } - } - break; - case Constants.EN_DOTTED: - if (horz) { - while (x1 + h < x2) { - afpDataStream.createLine( - pts2units(x1), - pts2units(y1), - pts2units(x1 + h), - pts2units(y1), - pts2units(h), - col - ); - x1 += 2 * h; - } - } else { - while (y1 + w < y2) { - afpDataStream.createLine( - pts2units(x1), - pts2units(y1), - pts2units(x1), - pts2units(y1 + w), - pts2units(w), - col - ); - y1 += 2 * w; - } - } - break; - case Constants.EN_GROOVE: - case Constants.EN_RIDGE: - { - float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); - if (horz) { - Color uppercol = ColorUtil.lightenColor(col, -colFactor); - Color lowercol = ColorUtil.lightenColor(col, colFactor); - float h3 = h / 3; - float ym1 = y1; - afpDataStream.createLine( - pts2units(x1), - pts2units(ym1), - pts2units(x2), - pts2units(ym1), - pts2units(h3), - uppercol - ); - afpDataStream.createLine( - pts2units(x1), - pts2units(ym1 + h3), - pts2units(x2), - pts2units(ym1 + h3), - pts2units(h3), - col - ); - afpDataStream.createLine( - pts2units(x1), - pts2units(ym1 + h3 + h3), - pts2units(x2), - pts2units(ym1 + h3 + h3), - pts2units(h3), - lowercol - ); - } else { - Color leftcol = ColorUtil.lightenColor(col, -colFactor); - Color rightcol = ColorUtil.lightenColor(col, colFactor); - float w3 = w / 3; - float xm1 = x1 + (w3 / 2); - afpDataStream.createLine( - pts2units(xm1), - pts2units(y1), - pts2units(xm1), - pts2units(y2), - pts2units(w3), - leftcol - ); - afpDataStream.createLine( - pts2units(xm1 + w3), - pts2units(y1), - pts2units(xm1 + w3), - pts2units(y2), - pts2units(w3), - col - ); - afpDataStream.createLine( - pts2units(xm1 + w3 + w3), - pts2units(y1), - pts2units(xm1 + w3 + w3), - pts2units(y2), - pts2units(w3), - rightcol - ); - } - break; - } - case Constants.EN_HIDDEN: - break; - case Constants.EN_INSET: - case Constants.EN_OUTSET: - default: - afpDataStream.createLine( - pts2units(x1), - pts2units(y1), - pts2units(horz ? x2 : x1), - pts2units(horz ? y1 : y2), - pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))), - col - ); - } + /** {@inheritDoc} */ + protected RendererContext instantiateRendererContext() { + return new AFPRendererContext(this, getMimeType()); } - /** - * {@inheritDoc} - */ - protected RendererContext createRendererContext(int x, int y, int width, int height, - Map foreignAttributes) { + /** {@inheritDoc} */ + protected RendererContext createRendererContext(int x, int y, int width, + int height, Map foreignAttributes) { RendererContext context; - context = super.createRendererContext(x, y, width, height, foreignAttributes); - context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, - Boolean.valueOf(!this.colorImages)); + context = super.createRendererContext(x, y, width, height, + foreignAttributes); + context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO, + this.fontInfo); + context.setProperty(AFPRendererContextConstants.AFP_RESOURCE_MANAGER, + this.resourceManager); + context.setProperty(AFPRendererContextConstants.AFP_PAINTING_STATE, paintingState); return context; } - private static final ImageFlavor[] FLAVORS = new ImageFlavor[] - {ImageFlavor.RAW_CCITTFAX, - ImageFlavor.GRAPHICS2D, - ImageFlavor.BUFFERED_IMAGE, - ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM}; + private static final ImageFlavor[] NATIVE_FLAVORS = new ImageFlavor[] { + ImageFlavor.XML_DOM, + /*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP + ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS, + ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; + + private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { + ImageFlavor.XML_DOM, + ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE }; /** {@inheritDoc} */ public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { uri = URISpecification.getURL(uri); - Rectangle posInt = new Rectangle( - (int)pos.getX(), - (int)pos.getY(), - (int)pos.getWidth(), - (int)pos.getHeight()); + paintingState.setImageUri(uri); + Point origin = new Point(currentIPPosition, currentBPPosition); + Rectangle posInt = new Rectangle( + (int)Math.round(pos.getX()), + (int)Math.round(pos.getY()), + (int)Math.round(pos.getWidth()), + (int)Math.round(pos.getHeight()) + ); int x = origin.x + posInt.x; int y = origin.y + posInt.y; - String name = null; - if (pageSegmentsMap != null) { - name = (String) pageSegmentsMap.get(uri); - } + String name = (String)pageSegmentMap.get(uri); if (name != null) { - afpDataStream.createIncludePageSegment(name, mpts2units(x), mpts2units(y)); + float[] srcPts = {x, y}; + int[] coords = unitConv.mpts2units(srcPts); + dataStream.createIncludePageSegment(name, coords[X], coords[Y]); } else { - ImageManager manager = getUserAgent().getFactory().getImageManager(); + ImageManager manager = userAgent.getFactory().getImageManager(); ImageInfo info = null; try { - ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); + ImageSessionContext sessionContext = userAgent + .getImageSessionContext(); info = manager.getImageInfo(uri, sessionContext); - //Only now fully load/prepare the image + // Only now fully load/prepare the image Map hints = ImageUtil.getDefaultHints(sessionContext); + + boolean nativeImagesSupported = paintingState.isNativeImagesSupported(); + ImageFlavor[] flavors = nativeImagesSupported ? NATIVE_FLAVORS : FLAVORS; + + // Load image org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, FLAVORS, hints, sessionContext); - - //...and process the image - if (img instanceof ImageGraphics2D) { - ImageGraphics2D imageG2D = (ImageGraphics2D)img; - RendererContext context = createRendererContext( - posInt.x, posInt.y, - posInt.width, posInt.height, foreignAttributes); - getGraphics2DAdapter().paintImage(imageG2D.getGraphics2DImagePainter(), - context, - origin.x + posInt.x, origin.y + posInt.y, - posInt.width, posInt.height); - } else if (img instanceof ImageRendered) { - ImageRendered imgRend = (ImageRendered)img; - RenderedImage ri = imgRend.getRenderedImage(); - - drawBufferedImage(ri, getResolution(), - posInt.x + currentIPPosition, - posInt.y + currentBPPosition, - posInt.width, - posInt.height); - } else if (img instanceof ImageRawCCITTFax) { - ImageRawCCITTFax ccitt = (ImageRawCCITTFax)img; - int afpx = mpts2units(posInt.x + currentIPPosition); - int afpy = mpts2units(posInt.y + currentBPPosition); - int afpw = mpts2units(posInt.getWidth()); - int afph = mpts2units(posInt.getHeight()); - int afpres = getResolution(); - ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph, - afpres, afpres); - io.setImageParameters( - (int) (ccitt.getSize().getDpiHorizontal() * 10), - (int) (ccitt.getSize().getDpiVertical() * 10), - ccitt.getSize().getWidthPx(), - ccitt.getSize().getHeightPx()); - int compression = ccitt.getCompression(); - switch (compression) { - case TIFFImage.COMP_FAX_G3_1D : - io.setImageEncoding((byte) 0x80); - break; - case TIFFImage.COMP_FAX_G3_2D : - io.setImageEncoding((byte) 0x81); - break; - case TIFFImage.COMP_FAX_G4_2D : - io.setImageEncoding((byte) 0x82); - break; - default: - throw new IllegalStateException( - "Invalid compression scheme: " + compression); - } - InputStream in = ccitt.createInputStream(); + info, flavors, hints, sessionContext); + + // Handle image + AFPImageHandler imageHandler + = (AFPImageHandler)imageHandlerRegistry.getHandler(img); + if (imageHandler != null) { + RendererContext rendererContext = createRendererContext( + x, y, posInt.width, posInt.height, foreignAttributes); + AFPRendererImageInfo rendererImageInfo = new AFPRendererImageInfo( + uri, pos, origin, info, img, rendererContext, foreignAttributes); + AFPDataObjectInfo dataObjectInfo = null; try { - byte[] buf = IOUtils.toByteArray(in); - io.setImageData(buf); - } finally { - IOUtils.closeQuietly(in); + dataObjectInfo = imageHandler.generateDataObjectInfo(rendererImageInfo); + // Create image + if (dataObjectInfo != null) { + resourceManager.createObject(dataObjectInfo); + } + } catch (IOException ioe) { + ResourceEventProducer eventProducer + = ResourceEventProducer.Provider.get(userAgent.getEventBroadcaster()); + eventProducer.imageWritingError(this, ioe); + throw ioe; } - } else if (img instanceof ImageXMLDOM) { - ImageXMLDOM imgXML = (ImageXMLDOM)img; - renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(), - pos, foreignAttributes); } else { - throw new UnsupportedOperationException("Unsupported image type: " + img); + throw new UnsupportedOperationException( + "No AFPImageHandler available for image: " + + info + " (" + img.getClass().getName() + ")"); } } catch (ImageException ie) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageError(this, (info != null ? info.toString() : uri), ie, null); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider + .get(userAgent.getEventBroadcaster()); + eventProducer.imageError(this, (info != null ? info.toString() + : uri), ie, null); } catch (FileNotFoundException fe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageNotFound(this, (info != null ? info.toString() : uri), fe, null); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider + .get(userAgent.getEventBroadcaster()); + eventProducer.imageNotFound(this, (info != null ? info.toString() + : uri), fe, null); } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageIOError(this, (info != null ? info.toString() : uri), ioe, null); + ResourceEventProducer eventProducer = ResourceEventProducer.Provider + .get(userAgent.getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() + : uri), ioe, null); } - - /* - ImageFactory fact = userAgent.getFactory().getImageFactory(); - FopImage fopimage = fact.getImage(url, userAgent); - if (fopimage == null) { - return; - } - if (!fopimage.load(FopImage.DIMENSIONS)) { - return; - } - String mime = fopimage.getMimeType(); - if ("text/xml".equals(mime) || MimeConstants.MIME_SVG.equals(mime)) { - if (!fopimage.load(FopImage.ORIGINAL_DATA)) { - return; - } - Document doc = ((XMLImage) fopimage).getDocument(); - String ns = ((XMLImage) fopimage).getNameSpace(); - - renderDocument(doc, ns, pos, foreignAttributes); - } else if (MimeConstants.MIME_EPS.equals(mime)) { - log.warn("EPS images are not supported by this renderer"); - */ - /* - * } else if (MimeConstants.MIME_JPEG.equals(mime)) { if - * (!fopimage.load(FopImage.ORIGINAL_DATA)) { return; } - * fact.releaseImage(url, userAgent); - * - * int x = mpts2units(pos.getX() + currentIPPosition); int y = - * mpts2units(pos.getY() + currentBPPosition); int w = - * mpts2units(pos.getWidth()); int h = - * mpts2units(pos.getHeight()); ImageObject io = - * _afpDataStream.getImageObject(); io.setImageViewport(x, y, w, - * h); io.setImageParameters( - * (int)(fopimage.getHorizontalResolution() * 10), - * (int)(fopimage.getVerticalResolution() * 10), - * fopimage.getWidth(), fopimage.getHeight() ); - * io.setImageIDESize((byte)fopimage.getBitsPerPixel()); - * io.setImageEncoding((byte)0x83); - * io.setImageData(fopimage.getRessourceBytes()); - *//* - } else if (MimeConstants.MIME_TIFF.equals(mime) - && fopimage instanceof TIFFImage) { - TIFFImage tiffImage = (TIFFImage) fopimage; - int x = mpts2units(pos.getX() + currentIPPosition); - int y = mpts2units(pos.getY() + currentBPPosition); - int w = mpts2units(pos.getWidth()); - int h = mpts2units(pos.getHeight()); - ImageObject io = afpDataStream.getImageObject(x, y, w, h, - getResolution(), getResolution()); - io.setImageParameters( - (int)(fopimage.getHorizontalResolution() * 10), - (int)(fopimage.getVerticalResolution() * 10), - fopimage.getWidth(), - fopimage.getHeight() - ); - if (tiffImage.getStripCount() == 1) { - int comp = tiffImage.getCompression(); - if (comp == 3) { - if (!fopimage.load(FopImage.ORIGINAL_DATA)) { - return; - } - io.setImageEncoding((byte)0x81); - io.setImageData(fopimage.getRessourceBytes()); - } else if (comp == 4) { - if (!fopimage.load(FopImage.ORIGINAL_DATA)) { - return; - } - io.setImageEncoding((byte)0x82); - io.setImageData(fopimage.getRessourceBytes()); - } else { - if (!fopimage.load(FopImage.BITMAP)) { - return; - } - convertToGrayScaleImage(io, fopimage.getBitmaps(), - fopimage.getWidth(), fopimage.getHeight()); - } - } else { - if (!fopimage.load(FopImage.BITMAP)) { - return; - } - convertToGrayScaleImage(io, fopimage.getBitmaps(), - fopimage.getWidth(), fopimage.getHeight()); - } - } else { - if (!fopimage.load(FopImage.BITMAP)) { - return; - } - fact.releaseImage(url, userAgent); - - int x = mpts2units(pos.getX() + currentIPPosition); - int y = mpts2units(pos.getY() + currentBPPosition); - int w = mpts2units(pos.getWidth()); - int h = mpts2units(pos.getHeight()); - ImageObject io = afpDataStream.getImageObject(x, y, w, h, - getResolution(), getResolution()); - io.setImageParameters( - (int)(fopimage.getHorizontalResolution() * 10), - (int)(fopimage.getVerticalResolution() * 10), - fopimage.getWidth(), - fopimage.getHeight() - ); - if (colorImages) { - io.setImageIDESize((byte)24); - io.setImageData(fopimage.getBitmaps()); - } else { - convertToGrayScaleImage(io, fopimage.getBitmaps(), - fopimage.getWidth(), fopimage.getHeight()); - } - }*/ } } @@ -1173,364 +465,155 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the OutputStream * @throws IOException * In case of an I/O error. + * @deprecated use ImageEncodingHelper.encodeRenderedImageAsRGB(image, out) + * directly instead */ public static void writeImage(RenderedImage image, OutputStream out) throws IOException { ImageEncodingHelper.encodeRenderedImageAsRGB(image, out); } - /** - * Draws a BufferedImage to AFP. - * - * @param image - * the RenderedImage - * @param imageResolution - * the resolution of the BufferedImage - * @param x - * the x coordinate (in mpt) - * @param y - * the y coordinate (in mpt) - * @param w - * the width of the viewport (in mpt) - * @param h - * the height of the viewport (in mpt) - */ - public void drawBufferedImage(RenderedImage image, int imageResolution, int x, - int y, int w, int h) { - int afpx = mpts2units(x); - int afpy = mpts2units(y); - int afpw = mpts2units(w); - int afph = mpts2units(h); - int afpres = getResolution(); - ByteArrayOutputStream baout = new ByteArrayOutputStream(); - try { - // Serialize image - //TODO Eventually, this should be changed not to buffer as this increases the - //memory consumption (see PostScript output) - writeImage(image, baout); - byte[] buf = baout.toByteArray(); - - // Generate image - ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, - afph, afpres, afpres); - io.setImageParameters(imageResolution, imageResolution, - image.getWidth(), image.getHeight()); - if (colorImages) { - io.setImageIDESize((byte)24); - io.setImageData(buf); - } else { - // TODO Teach it how to handle grayscale BufferedImages directly - // because this is pretty inefficient - convertToGrayScaleImage(io, buf, - image.getWidth(), image.getHeight(), this.bitsPerPixel); - } - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get( - getUserAgent().getEventBroadcaster()); - eventProducer.imageWritingError(this, ioe); - } - } - - /** - * Establishes a new foreground or fill color. - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void updateColor(Color col, boolean fill) { if (fill) { - currentColor = col; + paintingState.setColor(col); } } /** {@inheritDoc} */ - public List breakOutOfStateStack() { - log.debug("Block.FIXED --> break out"); - List breakOutList = new java.util.ArrayList(); - //Don't pop the last ViewPortPos (created by renderPage()) - while (this.viewPortPositions.size() > 1) { - breakOutList.add(0, popViewPortPos()); - } - return breakOutList; + public void restoreStateStackAfterBreakOut(List breakOutList) { + log.debug("Block.FIXED --> restoring context after break-out"); + paintingState.saveAll(breakOutList); } /** {@inheritDoc} */ - public void restoreStateStackAfterBreakOut(List breakOutList) { - log.debug("Block.FIXED --> restoring context after break-out"); - for (int i = 0, c = breakOutList.size(); i < c; i++) { - ViewPortPos vps = (ViewPortPos)breakOutList.get(i); - pushViewPortPos(vps); - } + protected List breakOutOfStateStack() { + log.debug("Block.FIXED --> break out"); + return paintingState.restoreAll(); } - /** Saves the graphics state of the rendering engine. */ + /** {@inheritDoc} */ public void saveGraphicsState() { - + paintingState.save(); } - /** Restores the last graphics state of the rendering engine. */ + /** {@inheritDoc} */ public void restoreGraphicsState() { - + paintingState.restore(); } - /** Indicates the beginning of a text object. */ - public void beginTextObject() { - - } - - /** Indicates the end of a text object. */ - public void endTextObject() { - - } - - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void renderImage(Image image, Rectangle2D pos) { - String url = image.getURL(); - drawImage(url, pos); + drawImage(image.getURL(), pos, image.getForeignAttributes()); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void renderText(TextArea text) { renderInlineAreaBackAndBorders(text); - String name = getInternalFontNameForArea(text); - currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - AFPFont tf = (AFPFont) fontInfo.getFonts().get(name); + // set font size + int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); + paintingState.setFontSize(fontSize); - Color col = (Color) text.getTrait(Trait.COLOR); + // register font as necessary + String internalFontName = getInternalFontNameForArea(text); + Map/*<String,FontMetrics>*/ fontMetricMap = fontInfo.getFonts(); + AFPFont font = (AFPFont)fontMetricMap.get(internalFontName); + AFPPageFonts pageFonts = paintingState.getPageFonts(); + AFPFontAttributes fontAttributes = pageFonts.registerFont(internalFontName, font, fontSize); - int vsci = mpts2units(tf.getWidth(' ', currentFontSize) / 1000 - + text.getTextWordSpaceAdjust() - + text.getTextLetterSpaceAdjust()); + // create text data info + AFPTextDataInfo textDataInfo = new AFPTextDataInfo(); - // word.getOffset() = only height of text itself - // currentBlockIPPosition: 0 for beginning of line; nonzero - // where previous line area failed to take up entire allocated space - int rx = currentIPPosition + text.getBorderAndPaddingWidthStart(); - int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset(); + int fontReference = fontAttributes.getFontReference(); + textDataInfo.setFontReference(fontReference); - // Set letterSpacing - //float ls = fs.getLetterSpacing() / this.currentFontSize; + int x = (currentIPPosition + text.getBorderAndPaddingWidthStart()); + int y = (currentBPPosition + text.getOffset() + text.getBaselineOffset()); - String worddata = text.getText(); + int[] coords = unitConv.mpts2units(new float[] {x, y} ); + textDataInfo.setX(coords[X]); + textDataInfo.setY(coords[Y]); - // Create an AFPFontAttributes object from the current font details - AFPFontAttributes afpFontAttributes = new AFPFontAttributes(name, tf, currentFontSize); + Color color = (Color) text.getTrait(Trait.COLOR); + textDataInfo.setColor(color); - if (!currentPageFonts.containsKey(afpFontAttributes.getFontKey())) { - // Font not found on current page, so add the new one - pageFontCounter++; - afpFontAttributes.setFontReference(pageFontCounter); - currentPageFonts.put( - afpFontAttributes.getFontKey(), - afpFontAttributes); + int textWordSpaceAdjust = text.getTextWordSpaceAdjust(); + int textLetterSpaceAdjust = text.getTextLetterSpaceAdjust(); + int textWidth = font.getWidth(' ', fontSize) / 1000; + int variableSpaceCharacterIncrement + = textWidth + textWordSpaceAdjust + textLetterSpaceAdjust; - } else { - // Use the previously stored font attributes - afpFontAttributes = (AFPFontAttributes) currentPageFonts.get( - afpFontAttributes.getFontKey()); - } + variableSpaceCharacterIncrement + = Math.round(unitConv.mpt2units(variableSpaceCharacterIncrement)); + textDataInfo.setVariableSpaceCharacterIncrement(variableSpaceCharacterIncrement); - // Try and get the encoding to use for the font - String encoding = null; + int interCharacterAdjustment + = Math.round(unitConv.mpt2units(textLetterSpaceAdjust)); + textDataInfo.setInterCharacterAdjustment(interCharacterAdjustment); - try { - encoding = tf.getCharacterSet(currentFontSize).getEncoding(); - } catch (Throwable ex) { - encoding = AFPConstants.EBCIDIC_ENCODING; - log.warn( - "renderText():: Error getting encoding for font '" - + tf.getFullName() - + "' - using default encoding " - + encoding); - } + CharacterSet charSet = font.getCharacterSet(fontSize); + String encoding = charSet.getEncoding(); + textDataInfo.setEncoding(encoding); + + String textString = text.getText(); + textDataInfo.setString(textString); try { - afpDataStream.createText( - afpFontAttributes.getFontReference(), - mpts2units(rx), - mpts2units(bl), - col, - vsci, - mpts2units(text.getTextLetterSpaceAdjust()), - worddata.getBytes(encoding)); - } catch (UnsupportedEncodingException usee) { - log.error( - "renderText:: Font " - + afpFontAttributes.getFontKey() - + " caused UnsupportedEncodingException"); + dataStream.createText(textDataInfo); + } catch (UnsupportedEncodingException e) { + AFPEventProducer eventProducer + = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster()); + eventProducer.characterSetEncodingError(this, charSet.getName(), encoding); } + // word.getOffset() = only height of text itself + // currentBlockIPPosition: 0 for beginning of line; nonzero + // where previous line area failed to take up entire allocated space super.renderText(text); - renderTextDecoration(tf, currentFontSize, text, bl, rx); + renderTextDecoration(font, fontSize, text, y, x); } /** - * {@inheritDoc} - */ - public void renderWord(WordArea word) { - // UNUSED - // String name = getInternalFontNameForArea(word.getParentArea()); - // int size = ((Integer) - // word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue(); - // AFPFont tf = (AFPFont) fontInfo.getFonts().get(name); - // - // String s = word.getWord(); - // - // FontMetrics metrics = fontInfo.getMetricsFor(name); - - super.renderWord(word); - } - - /** - * {@inheritDoc} - */ - public void renderSpace(SpaceArea space) { - // UNUSED - // String name = getInternalFontNameForArea(space.getParentArea()); - // int size = ((Integer) - // space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue(); - // AFPFont tf = (AFPFont) fontInfo.getFonts().get(name); - // - // String s = space.getSpace(); - // - // FontMetrics metrics = fontInfo.getMetricsFor(name); - - super.renderSpace(space); - } - - /** - * Render leader area. - * This renders a leader area which is an area with a rule. - * @param area the leader area to render + * Render leader area. This renders a leader area which is an area with a + * rule. + * + * @param area + * the leader area to render */ public void renderLeader(Leader area) { renderInlineAreaBackAndBorders(area); int style = area.getRuleStyle(); - float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f; + float startx = (currentIPPosition + area + .getBorderAndPaddingWidthStart()) / 1000f; float starty = (currentBPPosition + area.getOffset()) / 1000f; - float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() - + area.getIPD()) / 1000f; + float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() + area + .getIPD()) / 1000f; float ruleThickness = area.getRuleThickness() / 1000f; - Color col = (Color)area.getTrait(Trait.COLOR); + Color col = (Color) area.getTrait(Trait.COLOR); switch (style) { - case EN_SOLID: - case EN_DASHED: - case EN_DOUBLE: - case EN_DOTTED: - case EN_GROOVE: - case EN_RIDGE: - drawBorderLine(startx, starty, endx, starty + ruleThickness, - true, true, style, col); - break; - default: - throw new UnsupportedOperationException("rule style not supported"); + case EN_SOLID: + case EN_DASHED: + case EN_DOUBLE: + case EN_DOTTED: + case EN_GROOVE: + case EN_RIDGE: + drawBorderLine(startx, starty, endx, starty + ruleThickness, true, + true, style, col); + break; + default: + throw new UnsupportedOperationException("rule style not supported"); } super.renderLeader(area); } /** - * Sets the AFPRenderer options - * @param options the <code>Map</code> containing the options - */ -// UNUSED -// public void setOptions(Map options) { -// -// this.afpOptions = options; -// -// } - /** - * Determines the orientation from the string representation, this method - * guarantees to return a value of either 0, 90, 180 or 270. - * - * @return the orientation - */ -// UNUSED -// private int getOrientation(String orientationString) { -// -// int orientation = 0; -// if (orientationString != null && orientationString.length() > 0) { -// try { -// orientation = Integer.parseInt(orientationString); -// } catch (NumberFormatException nfe) { -// log.error("Cannot use orientation of " + orientation -// + " defaulting to zero."); -// orientation = 0; -// } -// } else { -// orientation = 0; -// } -// switch (orientation) { -// case 0: -// break; -// case 90: -// break; -// case 180: -// break; -// case 270: -// break; -// default: -// log.error("Cannot use orientation of " + orientation -// + " defaulting to zero."); -// orientation = 0; -// break; -// } -// -// return orientation; -// -// } - /** - * Sets the rotation to be used for portrait pages, valid values are 0 - * (default), 90, 180, 270. - * - * @param rotation - * The rotation in degrees. - */ - public void setPortraitRotation(int rotation) { - - if (rotation == 0 - || rotation == 90 - || rotation == 180 - || rotation == 270) { - portraitRotation = rotation; - } else { - throw new IllegalArgumentException("The portrait rotation must be one" - + " of the values 0, 90, 180, 270"); - - } - - } - - /** - * Sets the rotation to be used for landsacpe pages, valid values are 0, 90, - * 180, 270 (default). - * - * @param rotation - * The rotation in degrees. - */ - public void setLandscapeRotation(int rotation) { - - if (rotation == 0 - || rotation == 90 - || rotation == 180 - || rotation == 270) { - landscapeRotation = rotation; - } else { - throw new IllegalArgumentException("The landscape rotation must be one" - + " of the values 0, 90, 180, 270"); - } - - } - - /** * Get the MIME type of the renderer. * - * @return The MIME type of the renderer + * @return The MIME type of the renderer */ public String getMimeType() { return MimeConstants.MIME_AFP; @@ -1540,46 +623,40 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * Method to render the page extension. * <p> * - * @param pageViewport the page object + * @param pageViewport + * the page object */ private void renderPageObjectExtensions(PageViewport pageViewport) { - - pageSegmentsMap = null; + pageSegmentMap.clear(); if (pageViewport.getExtensionAttachments() != null && pageViewport.getExtensionAttachments().size() > 0) { // Extract all AFPPageSetup instances from the attachment list on // the s-p-m - Iterator i = pageViewport.getExtensionAttachments().iterator(); - while (i.hasNext()) { - ExtensionAttachment attachment = (ExtensionAttachment)i.next(); + Iterator it = pageViewport.getExtensionAttachments().iterator(); + while (it.hasNext()) { + ExtensionAttachment attachment = (ExtensionAttachment) it.next(); if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) { AFPPageSetup aps = (AFPPageSetup) attachment; String element = aps.getElementName(); if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) { String overlay = aps.getName(); if (overlay != null) { - afpDataStream.createIncludePageOverlay(overlay); + dataStream.createIncludePageOverlay(overlay); } } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT .equals(element)) { String name = aps.getName(); String source = aps.getValue(); - if (pageSegmentsMap == null) { - pageSegmentsMap = new HashMap(); - } - pageSegmentsMap.put(source, name); + pageSegmentMap.put(source, name); } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT .equals(element)) { String name = aps.getName(); String value = aps.getValue(); - if (pageSegmentsMap == null) { - pageSegmentsMap = new HashMap(); - } - afpDataStream.createTagLogicalElement(name, value); + dataStream.createTagLogicalElement(name, value); } else if (AFPElementMapping.NO_OPERATION.equals(element)) { String content = aps.getContent(); if (content != null) { - afpDataStream.createNoOperation(content); + dataStream.createNoOperation(content); } } } @@ -1589,206 +666,25 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** - * Converts FOP mpt measurement to afp measurement units - * @param mpt the millipoints value - */ - private int mpts2units(int mpt) { - return mpts2units((double) mpt); - } - - /** - * Converts FOP pt measurement to afp measurement units - * @param mpt the millipoints value - */ - private int pts2units(float mpt) { - return mpts2units(mpt * 1000d); - } - - /** - * Converts FOP mpt measurement to afp measurement units + * Sets the rotation to be used for portrait pages, valid values are 0 + * (default), 90, 180, 270. * - * @param mpt - * the millipoints value - * @return afp measurement unit value + * @param rotation + * The rotation in degrees. */ - private int mpts2units(double mpt) { - return (int)Math.round(mpt / (DPI_CONVERSION_FACTOR / getResolution())); + public void setPortraitRotation(int rotation) { + paintingState.setPortraitRotation(rotation); } /** - * Converts a byte array containing 24 bit RGB image data to a grayscale - * image. + * Sets the rotation to be used for landsacpe pages, valid values are 0, 90, + * 180, 270 (default). * - * @param io - * the target image object - * @param raw - * the buffer containing the RGB image data - * @param width - * the width of the image in pixels - * @param height - * the height of the image in pixels - * @param bitsPerPixel - * the number of bits to use per pixel + * @param rotation + * The rotation in degrees. */ - protected static void convertToGrayScaleImage(ImageObject io, byte[] raw, int width, - int height, int bitsPerPixel) { - int pixelsPerByte = 8 / bitsPerPixel; - int bytewidth = (width / pixelsPerByte); - if ((width % pixelsPerByte) != 0) { - bytewidth++; - } - byte[] bw = new byte[height * bytewidth]; - byte ib; - for (int y = 0; y < height; y++) { - ib = 0; - int i = 3 * y * width; - for (int x = 0; x < width; x++, i += 3) { - - // see http://www.jguru.com/faq/view.jsp?EID=221919 - double greyVal = 0.212671d * ((int) raw[i] & 0xff) + 0.715160d - * ((int) raw[i + 1] & 0xff) + 0.072169d - * ((int) raw[i + 2] & 0xff); - switch (bitsPerPixel) { - case 1: - if (greyVal < 128) { - ib |= (byte) (1 << (7 - (x % 8))); - } - break; - case 4: - greyVal /= 16; - ib |= (byte) ((byte) greyVal << ((1 - (x % 2)) * 4)); - break; - case 8: - ib = (byte) greyVal; - break; - default: - throw new UnsupportedOperationException( - "Unsupported bits per pixel: " + bitsPerPixel); - } - - if ((x % pixelsPerByte) == (pixelsPerByte - 1) - || ((x + 1) == width)) { - bw[(y * bytewidth) + (x / pixelsPerByte)] = ib; - ib = 0; - } - } - } - io.setImageIDESize((byte) bitsPerPixel); - io.setImageData(bw); - } - - private final class ViewPortPos { - private int x = 0; - - private int y = 0; - - private int rot = 0; - - private ViewPortPos() { - } - - private ViewPortPos(Rectangle2D view, CTM ctm) { - ViewPortPos currentVP = (ViewPortPos) viewPortPositions - .get(viewPortPositions.size() - 1); - int xOrigin; - int yOrigin; - int width; - int height; - switch (currentVP.rot) { - case 90: - width = mpts2units(view.getHeight()); - height = mpts2units(view.getWidth()); - xOrigin = pageWidth - width - mpts2units(view.getY()) - - currentVP.y; - yOrigin = mpts2units(view.getX()) + currentVP.x; - break; - case 180: - width = mpts2units(view.getWidth()); - height = mpts2units(view.getHeight()); - xOrigin = pageWidth - width - mpts2units(view.getX()) - - currentVP.x; - yOrigin = pageHeight - height - mpts2units(view.getY()) - - currentVP.y; - break; - case 270: - width = mpts2units(view.getHeight()); - height = mpts2units(view.getWidth()); - xOrigin = mpts2units(view.getY()) + currentVP.y; - yOrigin = pageHeight - height - mpts2units(view.getX()) - - currentVP.x; - break; - default: - xOrigin = mpts2units(view.getX()) + currentVP.x; - yOrigin = mpts2units(view.getY()) + currentVP.y; - width = mpts2units(view.getWidth()); - height = mpts2units(view.getHeight()); - break; - } - this.rot = currentVP.rot; - double[] ctmf = ctm.toArray(); - if (ctmf[0] == 0.0d && ctmf[1] == -1.0d && ctmf[2] == 1.0d - && ctmf[3] == 0.d) { - this.rot += 270; - } else if (ctmf[0] == -1.0d && ctmf[1] == 0.0d && ctmf[2] == 0.0d - && ctmf[3] == -1.0d) { - this.rot += 180; - } else if (ctmf[0] == 0.0d && ctmf[1] == 1.0d && ctmf[2] == -1.0d - && ctmf[3] == 0.0d) { - this.rot += 90; - } - this.rot %= 360; - switch (this.rot) { - /* - * case 0: this.x = mpts2units(view.getX()) + x; this.y = - * mpts2units(view.getY()) + y; break; case 90: this.x = - * mpts2units(view.getY()) + y; this.y = _pageWidth - - * mpts2units(view.getX() + view.getWidth()) - x; break; case 180: - * this.x = _pageWidth - mpts2units(view.getX() + view.getWidth()) - - * x; this.y = _pageHeight - mpts2units(view.getY() + - * view.getHeight()) - y; break; case 270: this.x = _pageHeight - - * mpts2units(view.getY() + view.getHeight()) - y; this.y = - * mpts2units(view.getX()) + x; break; - */ - case 0: - this.x = xOrigin; - this.y = yOrigin; - break; - case 90: - this.x = yOrigin; - this.y = pageWidth - width - xOrigin; - break; - case 180: - this.x = pageWidth - width - xOrigin; - this.y = pageHeight - height - yOrigin; - break; - case 270: - this.x = pageHeight - height - yOrigin; - this.y = xOrigin; - break; - default: - } - } - - public String toString() { - return "x:" + x + " y:" + y + " rot:" + rot; - } - - } - - private List viewPortPositions = new ArrayList(); - - private void pushViewPortPos(ViewPortPos vpp) { - viewPortPositions.add(vpp); - afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot); - } - - private ViewPortPos popViewPortPos() { - ViewPortPos current = (ViewPortPos)viewPortPositions.remove(viewPortPositions.size() - 1); - if (viewPortPositions.size() > 0) { - ViewPortPos vpp = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1); - afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot); - } - return current; + public void setLandscapeRotation(int rotation) { + paintingState.setLandscapeRotation(rotation); } /** @@ -1798,17 +694,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * number of bits per pixel */ public void setBitsPerPixel(int bitsPerPixel) { - this.bitsPerPixel = bitsPerPixel; - switch (bitsPerPixel) { - case 1: - case 4: - case 8: - break; - default: - log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8."); - bitsPerPixel = 8; - break; - } + paintingState.setBitsPerPixel(bitsPerPixel); } /** @@ -1818,7 +704,17 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * color image output */ public void setColorImages(boolean colorImages) { - this.colorImages = colorImages; + paintingState.setColorImages(colorImages); + } + + /** + * Sets whether images are supported natively or not + * + * @param nativeImages + * native image support + */ + public void setNativeImagesSupported(boolean nativeImages) { + paintingState.setNativeImagesSupported(nativeImages); } /** @@ -1828,17 +724,73 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the output resolution (dpi) */ public void setResolution(int resolution) { - if (log.isDebugEnabled()) { - log.debug("renderer-resolution set to: " + resolution + "dpi"); - } - this.resolution = resolution; + paintingState.setResolution(resolution); } /** * Returns the output/device resolution. + * * @return the resolution in dpi */ public int getResolution() { - return this.resolution; + return paintingState.getResolution(); + } + + /** + * Sets the default resource group file path + * @param filePath the default resource group file path + */ + public void setDefaultResourceGroupFilePath(String filePath) { + resourceManager.setDefaultResourceGroupFilePath(filePath); + } + + /** {@inheritDoc} */ + protected void establishTransformationMatrix(AffineTransform at) { + saveGraphicsState(); + concatenateTransformationMatrix(at); } + + /** {@inheritDoc} */ + public void clip() { + // TODO +// log.debug("NYI clip()"); + } + + /** {@inheritDoc} */ + public void clipRect(float x, float y, float width, float height) { + // TODO +// log.debug("NYI clipRect(x=" + x + ",y=" + y +// + ",width=" + width + ", height=" + height + ")"); + } + + /** {@inheritDoc} */ + public void moveTo(float x, float y) { + // TODO +// log.debug("NYI moveTo(x=" + x + ",y=" + y + ")"); + } + + /** {@inheritDoc} */ + public void lineTo(float x, float y) { + // TODO +// log.debug("NYI lineTo(x=" + x + ",y=" + y + ")"); + } + + /** {@inheritDoc} */ + public void closePath() { + // TODO +// log.debug("NYI closePath()"); + } + + /** Indicates the beginning of a text object. */ + public void beginTextObject() { + //TODO PDF specific maybe? +// log.debug("NYI beginTextObject()"); + } + + /** Indicates the end of a text object. */ + public void endTextObject() { + //TODO PDF specific maybe? +// log.debug("NYI endTextObject()"); + } + } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index 65e39daad..5982ae5b0 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -19,10 +19,17 @@ package org.apache.fop.render.afp; +import java.io.File; import java.util.List; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; + +import org.apache.fop.afp.fonts.AFPFontInfo; +import org.apache.fop.afp.fonts.CharacterSet; +import org.apache.fop.afp.fonts.FopCharacterSet; +import org.apache.fop.afp.fonts.OutlineFont; +import org.apache.fop.afp.fonts.RasterFont; import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fonts.FontTriplet; @@ -30,11 +37,6 @@ import org.apache.fop.fonts.FontUtil; import org.apache.fop.fonts.Typeface; import org.apache.fop.render.PrintRendererConfigurator; import org.apache.fop.render.Renderer; -import org.apache.fop.render.afp.fonts.AFPFontInfo; -import org.apache.fop.render.afp.fonts.CharacterSet; -import org.apache.fop.render.afp.fonts.FopCharacterSet; -import org.apache.fop.render.afp.fonts.OutlineFont; -import org.apache.fop.render.afp.fonts.RasterFont; import org.apache.fop.util.LogUtil; /** @@ -44,6 +46,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { /** * Default constructor + * * @param userAgent user agent */ public AFPRendererConfigurator(FOUserAgent userAgent) { @@ -54,16 +57,17 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { throws ConfigurationException { Configuration[] triple = fontCfg.getChildren("font-triplet"); - List tripleList = new java.util.ArrayList(); + List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/(); if (triple.length == 0) { log.error("Mandatory font configuration element '<font-triplet...' is missing"); return null; } for (int j = 0; j < triple.length; j++) { int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight")); - tripleList.add(new FontTriplet(triple[j].getAttribute("name"), - triple[j].getAttribute("style"), - weight)); + FontTriplet triplet = new FontTriplet(triple[j].getAttribute("name"), + triple[j].getAttribute("style"), + weight); + tripletList.add(triplet); } //build the fonts @@ -121,7 +125,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { try { Typeface tf = (Typeface)clazz.newInstance(); font.addCharacterSet(size, new FopCharacterSet( - codepage, encoding, characterset, size, tf)); + codepage, encoding, characterset, tf)); } catch (Exception ie) { String msg = "The base 14 font class " + clazz.getName() + " could not be instantiated"; @@ -137,21 +141,17 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { codepage, encoding, characterset, path)); } } - return new AFPFontInfo(font, tripleList); + return new AFPFontInfo(font, tripletList); } else if ("outline".equalsIgnoreCase(type)) { - String characterset = afpFontCfg.getAttribute("characterset"); if (characterset == null) { log.error("Mandatory afp-font configuration attribute 'characterset=' is missing"); return null; } String name = afpFontCfg.getAttribute("name", characterset); - CharacterSet characterSet = null; - String base14 = afpFontCfg.getAttribute("base14-font", null); - if (base14 != null) { try { Class clazz = Class.forName("org.apache.fop.fonts.base14." @@ -159,7 +159,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { try { Typeface tf = (Typeface)clazz.newInstance(); characterSet = new FopCharacterSet( - codepage, encoding, characterset, 1, tf); + codepage, encoding, characterset, tf); } catch (Exception ie) { String msg = "The base 14 font class " + clazz.getName() + " could not be instantiated"; @@ -175,7 +175,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { } // Create a new font object OutlineFont font = new OutlineFont(name, characterSet); - return new AFPFontInfo(font, tripleList); + return new AFPFontInfo(font, tripletList); } else { log.error("No or incorrect type attribute"); } @@ -184,36 +184,45 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { /** * Builds a list of AFPFontInfo objects for use with the setup() method. + * * @param cfg Configuration object * @return List the newly created list of fonts * @throws ConfigurationException if something's wrong with the config data */ - private List buildFontListFromConfiguration(Configuration cfg) + private List/*<AFPFontInfo>*/ buildFontListFromConfiguration(Configuration cfg) throws ConfigurationException { - List fontList = new java.util.ArrayList(); + List/*<AFPFontInfo>*/ fontList = new java.util.ArrayList(); Configuration[] font = cfg.getChild("fonts").getChildren("font"); + final String fontPath = null; for (int i = 0; i < font.length; i++) { - AFPFontInfo afi = buildFont(font[i], null); + AFPFontInfo afi = buildFont(font[i], fontPath); if (afi != null) { if (log.isDebugEnabled()) { log.debug("Adding font " + afi.getAFPFont().getFontName()); - for (int j = 0; j < afi.getFontTriplets().size(); ++j) { - FontTriplet triplet = (FontTriplet) afi.getFontTriplets().get(j); + List/*<FontTriplet>*/ fontTriplets = afi.getFontTriplets(); + for (int j = 0; j < fontTriplets.size(); ++j) { + FontTriplet triplet = (FontTriplet) fontTriplets.get(j); log.debug(" Font triplet " + triplet.getName() + ", " + triplet.getStyle() + ", " + triplet.getWeight()); } } - fontList.add(afi); } } return fontList; } + /** images are converted to grayscale bitmapped IOCA */ + private static final String IMAGES_MODE_GRAYSCALE = "b+w"; + + /** images are converted to color bitmapped IOCA */ + private static final String IMAGES_MODE_COLOR = "color"; + /** * Configure the AFP renderer. + * * @param renderer AFP renderer * @throws FOPException fop exception * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer) @@ -223,24 +232,56 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { if (cfg != null) { AFPRenderer afpRenderer = (AFPRenderer)renderer; try { - List fontList = buildFontListFromConfiguration(cfg); + List/*<AFPFontInfo>*/ fontList = buildFontListFromConfiguration(cfg); afpRenderer.setFontList(fontList); } catch (ConfigurationException e) { LogUtil.handleException(log, e, userAgent.getFactory().validateUserConfigStrictly()); } + // image information Configuration imagesCfg = cfg.getChild("images"); - if (!"color".equalsIgnoreCase(imagesCfg.getAttribute("mode", "b+w"))) { - afpRenderer.setBitsPerPixel(imagesCfg.getAttributeAsInteger("bits-per-pixel", 8)); - } else { + + // default to grayscale images + String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE); + if (IMAGES_MODE_COLOR.equals(imagesMode)) { afpRenderer.setColorImages(true); + } else { + afpRenderer.setColorImages(false); + // default to 8 bits per pixel + int bitsPerPixel = imagesCfg.getAttributeAsInteger("bits-per-pixel", 8); + afpRenderer.setBitsPerPixel(bitsPerPixel); } + // native image support + boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", false); + afpRenderer.setNativeImagesSupported(nativeImageSupport); + + // renderer resolution Configuration rendererResolutionCfg = cfg.getChild("renderer-resolution", false); if (rendererResolutionCfg != null) { afpRenderer.setResolution(rendererResolutionCfg.getValueAsInteger(240)); } + + // a default external resource group file setting + Configuration resourceGroupFileCfg + = cfg.getChild("resource-group-file", false); + if (resourceGroupFileCfg != null) { + String resourceGroupDest = null; + try { + resourceGroupDest = resourceGroupFileCfg.getValue(); + } catch (ConfigurationException e) { + LogUtil.handleException(log, e, + userAgent.getFactory().validateUserConfigStrictly()); + } + File resourceGroupFile = new File(resourceGroupDest); + if (resourceGroupFile.canWrite()) { + afpRenderer.setDefaultResourceGroupFilePath(resourceGroupDest); + } else { + log.warn("Unable to write to default external resource group file '" + + resourceGroupDest + "'"); + } + } } } } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererContext.java b/src/java/org/apache/fop/render/afp/AFPRendererContext.java new file mode 100644 index 000000000..8d544a7c4 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPRendererContext.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.util.Map; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceLevel; +import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.render.AbstractRenderer; +import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContextConstants; + +public class AFPRendererContext extends RendererContext { + + /** + * Main constructor + * + * @param renderer the current renderer + * @param mime the MIME type of the output that's generated. + */ + public AFPRendererContext(AbstractRenderer renderer, String mime) { + super(renderer, mime); + } + + /** + * Returns a new AFPInfo for this renderer context + * + * @return an AFPInfo for this renderer context + */ + public AFPInfo getInfo() { + AFPInfo info = new AFPInfo(); + info.setWidth(((Integer)getProperty(RendererContextConstants.WIDTH)).intValue()); + info.setHeight(((Integer)getProperty(RendererContextConstants.HEIGHT)).intValue()); + info.setX(((Integer)getProperty(RendererContextConstants.XPOS)).intValue()); + info.setY(((Integer)getProperty(RendererContextConstants.YPOS)).intValue()); + info.setHandlerConfiguration((Configuration)getProperty( + RendererContextConstants.HANDLER_CONFIGURATION)); + info.setFontInfo((org.apache.fop.fonts.FontInfo)getProperty( + AFPRendererContextConstants.AFP_FONT_INFO)); + info.setPaintingState((AFPPaintingState)getProperty( + AFPRendererContextConstants.AFP_PAINTING_STATE)); + info.setResourceManager(((AFPResourceManager)getProperty( + AFPRendererContextConstants.AFP_RESOURCE_MANAGER))); + + Map foreignAttributes = (Map)getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); + if (foreignAttributes != null) { + String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE); + boolean paintAsBitmap = BITMAP.equalsIgnoreCase(conversionMode); + info.setPaintAsBitmap(paintAsBitmap); + + AFPForeignAttributeReader foreignAttributeReader + = new AFPForeignAttributeReader(); + AFPResourceInfo resourceInfo + = foreignAttributeReader.getResourceInfo(foreignAttributes); + // default to inline level if painted as GOCA + if (!resourceInfo.levelChanged() && !paintAsBitmap) { + resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE)); + } + info.setResourceInfo(resourceInfo); + } + return info; + } +} diff --git a/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java index 428e5b1ca..3302b7f3c 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java @@ -32,4 +32,12 @@ public interface AFPRendererContextConstants extends RendererContextConstants { */ String AFP_GRAYSCALE = "afpGrayscale"; + /** The font information for the AFP renderer. */ + String AFP_FONT_INFO = "afpFontInfo"; + + /** The afp resource manager */ + String AFP_RESOURCE_MANAGER = "afpResourceManager"; + + /** The afp painting state */ + String AFP_PAINTING_STATE = "afpPaintingState"; } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java b/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java new file mode 100644 index 000000000..2687d9071 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.awt.Point; +import java.awt.geom.Rectangle2D; +import java.util.Map; + +import org.apache.fop.render.RendererContext; +import org.apache.xmlgraphics.image.loader.Image; +import org.apache.xmlgraphics.image.loader.ImageInfo; + +/** + * The AFP image information + */ +public class AFPRendererImageInfo { + + /** the image uri */ + protected final String uri; + + /** the current pos */ + protected final Rectangle2D pos; + + /** the origin */ + protected final Point origin; + + /** the foreign attributes */ + protected final Map foreignAttributes; + + /** the image info */ + protected final ImageInfo info; + + /** the image */ + protected final Image img; + + /** the renderer context */ + protected RendererContext rendererContext; + + /** + * Main constructor + * + * @param uri the image uri + * @param pos the image content area + * @param origin the current position + * @param info the image info + * @param img the image + * @param rendererContext the renderer context + * @param foreignAttributes the foreign attributes + */ + public AFPRendererImageInfo(String uri, Rectangle2D pos, Point origin, + ImageInfo info, Image img, RendererContext rendererContext, Map foreignAttributes) { + this.uri = uri; + this.pos = pos; + this.origin = origin; + this.info = info; + this.img = img; + this.rendererContext = rendererContext; + this.foreignAttributes = foreignAttributes; + } + + /** + * Sets the renderer context + * + * @param rendererContext the renderer context + */ + public void setRendererContext(RendererContext rendererContext) { + this.rendererContext = rendererContext; + } + + /** + * Returns the image info + * + * @return the image info + */ + public ImageInfo getImageInfo() { + return this.info; + } + + /** + * Returns the image + * + * @return the image + */ + public Image getImage() { + return this.img; + } + + /** + * Returns the renderer context + * + * @return the renderer context + */ + public RendererContext getRendererContext() { + return this.rendererContext; + } + + /** + * Return the foreign attributes + * @return the foreign attributes + */ + public Map getForeignAttributes() { + return this.foreignAttributes; + } + + /** + * Return the uri + * + * @return the uri + */ + public String getURI() { + return this.uri; + } + + /** + * Return the origin + * + * @return the origin + */ + public Point getOrigin() { + return this.origin; + } + + /** + * Return the position + * + * @return the position + */ + public Rectangle2D getPosition() { + return this.pos; + } + + /** {@inheritDoc} */ + public String toString() { + return "AFPRendererImageInfo{\n" + + "\turi=" + uri + ",\n" + + "\tinfo=" + info + ",\n" + + "\tpos=" + pos + ",\n" + + "\torigin=" + origin + ",\n" + + "\timg=" + img + ",\n" + + "\tforeignAttributes=" + foreignAttributes + ",\n" + + "\trendererContext=" + rendererContext + "\n" + + "}"; + + } +} diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 5f077fdc6..161217a54 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -20,9 +20,39 @@ package org.apache.fop.render.afp; // FOP +import java.awt.Dimension; +import java.awt.geom.AffineTransform; +import java.io.IOException; + +import org.w3c.dom.Document; + +import org.apache.batik.bridge.BridgeContext; +import org.apache.batik.dom.svg.SVGDOMImplementation; +import org.apache.batik.gvt.GraphicsNode; + +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; +import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; +import org.apache.xmlgraphics.util.MimeConstants; + +import org.apache.fop.afp.AFPGraphics2D; +import org.apache.fop.afp.AFPGraphicsObjectInfo; +import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.fop.afp.AFPResourceInfo; +import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.afp.AFPUnitConverter; +import org.apache.fop.afp.svg.AFPBridgeContext; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fonts.FontInfo; +import org.apache.fop.image.loader.batik.BatikUtil; +import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContext.RendererContextWrapper; +import org.apache.fop.svg.SVGEventProducer; +import org.apache.fop.svg.SVGUserAgent; /** * AFP XML handler for SVG. Uses Apache Batik for SVG processing. @@ -31,6 +61,151 @@ import org.apache.fop.render.RendererContext; */ public class AFPSVGHandler extends AbstractGenericSVGHandler { + private boolean paintAsBitmap = false; + + /** {@inheritDoc} */ + public void handleXML(RendererContext context, + Document doc, String ns) throws Exception { + if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { + renderSVGDocument(context, doc); + } + } + + /** + * Render the SVG document. + * + * @param rendererContext the renderer context + * @param doc the SVG document + * @throws IOException In case of an I/O error while painting the image + */ + protected void renderSVGDocument(final RendererContext rendererContext, + final Document doc) throws IOException { + + AFPRendererContext afpRendererContext = (AFPRendererContext)rendererContext; + AFPInfo afpInfo = afpRendererContext.getInfo(); + + this.paintAsBitmap = afpInfo.paintAsBitmap(); + + FOUserAgent userAgent = rendererContext.getUserAgent(); + + // fallback paint as bitmap + String uri = getDocumentURI(doc); + if (paintAsBitmap) { + try { + super.renderSVGDocument(rendererContext, doc); + } catch (IOException ioe) { + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + userAgent.getEventBroadcaster()); + eventProducer.svgRenderingError(this, ioe, uri); + } + return; + } + + // Create a new AFPGraphics2D + final boolean textAsShapes = afpInfo.strokeText(); + AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes); + + AFPPaintingState paintingState = g2d.getPaintingState(); + paintingState.setImageUri(uri); + + // Create an AFPBridgeContext + BridgeContext bridgeContext = createBridgeContext(userAgent, g2d); + + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(doc); + + // Build the SVG DOM and provide the painter with it + GraphicsNode root = buildGraphicsNode(userAgent, bridgeContext, clonedDoc); + + // Create Graphics2DImagePainter + final RendererContextWrapper wrappedContext + = RendererContext.wrapRendererContext(rendererContext); + Dimension imageSize = getImageSize(wrappedContext); + Graphics2DImagePainter painter + = createGrapics2DImagePainter(bridgeContext, root, imageSize); + + // Create AFPObjectAreaInfo + RendererContextWrapper rctx = RendererContext.wrapRendererContext(rendererContext); + int x = rctx.getCurrentXPosition(); + int y = rctx.getCurrentYPosition(); + int width = afpInfo.getWidth(); + int height = afpInfo.getHeight(); + int resolution = afpInfo.getResolution(); + + paintingState.save(); // save + + AFPObjectAreaInfo objectAreaInfo + = createObjectAreaInfo(paintingState, x, y, width, height, resolution); + + // Create AFPGraphicsObjectInfo + AFPResourceInfo resourceInfo = afpInfo.getResourceInfo(); + AFPGraphicsObjectInfo graphicsObjectInfo = createGraphicsObjectInfo( + paintingState, painter, userAgent, resourceInfo, g2d); + graphicsObjectInfo.setObjectAreaInfo(objectAreaInfo); + + // Create the GOCA GraphicsObject in the DataStream + AFPResourceManager resourceManager = afpInfo.getResourceManager(); + resourceManager.createObject(graphicsObjectInfo); + + paintingState.restore(); // resume + } + + private AFPObjectAreaInfo createObjectAreaInfo(AFPPaintingState paintingState, + int x, int y, int width, int height, int resolution) { + // set the data object parameters + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); + + AffineTransform at = paintingState.getData().getTransform(); + at.translate(x, y); + objectAreaInfo.setX((int)Math.round(at.getTranslateX())); + objectAreaInfo.setY((int)Math.round(at.getTranslateY())); + + objectAreaInfo.setWidthRes(resolution); + objectAreaInfo.setHeightRes(resolution); + + AFPUnitConverter unitConv = paintingState.getUnitConverter(); + objectAreaInfo.setWidth(Math.round(unitConv.mpt2units(width))); + objectAreaInfo.setHeight(Math.round(unitConv.mpt2units(height))); + + int rotation = paintingState.getRotation(); + objectAreaInfo.setRotation(rotation); + + return objectAreaInfo; + } + + private AFPGraphicsObjectInfo createGraphicsObjectInfo(AFPPaintingState paintingState, Graphics2DImagePainter painter, + FOUserAgent userAgent, AFPResourceInfo resourceInfo, AFPGraphics2D g2d) { + AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo(); + + String uri = paintingState.getImageUri(); + graphicsObjectInfo.setUri(uri); + + graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA); + + graphicsObjectInfo.setResourceInfo(resourceInfo); + + graphicsObjectInfo.setPainter(painter); + + // Set the afp graphics 2d implementation + graphicsObjectInfo.setGraphics2D(g2d); + + return graphicsObjectInfo; + } + + public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) { + ImageManager imageManager = userAgent.getFactory().getImageManager(); + + SVGUserAgent svgUserAgent + = new SVGUserAgent(userAgent, new AffineTransform()); + + ImageSessionContext imageSessionContext = userAgent.getImageSessionContext(); + + FontInfo fontInfo = g2d.getFontInfo(); + return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext, + new AffineTransform(), g2d); + } + /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { return (renderer instanceof AFPRenderer); @@ -39,9 +214,29 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { /** {@inheritDoc} */ protected void updateRendererContext(RendererContext context) { //Work around a problem in Batik: Gradients cannot be done in ColorSpace.CS_GRAY - context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, - Boolean.FALSE); + context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, Boolean.FALSE); } -} + /** {@inheritDoc} */ + protected Graphics2DImagePainter createGrapics2DImagePainter(BridgeContext ctx, GraphicsNode root, Dimension imageSize) { + Graphics2DImagePainter painter = null; + if (paintAsBitmap()) { + // paint as IOCA Image + painter = super.createGraphics2DImagePainter(root, ctx, imageSize); + } else { + // paint as GOCA Graphics + painter = new Graphics2DImagePainterImpl(root, ctx, imageSize); + } + return painter; + } + /** + * Returns true if the SVG is to be painted as a bitmap + * + * @return true if the SVG is to be painted as a bitmap + */ + private boolean paintAsBitmap() { + return paintAsBitmap; + } + +} diff --git a/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java b/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java new file mode 100644 index 000000000..ae8ac9950 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AbstractAFPImageHandlerRawStream.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.render.afp; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.apache.fop.afp.AFPDataObjectInfo; +import org.apache.fop.afp.AFPObjectAreaInfo; +import org.apache.fop.afp.AFPPaintingState; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; + +/** + * A base abstract AFP raw stream image handler + */ +public abstract class AbstractAFPImageHandlerRawStream extends AFPImageHandler { + + /** {@inheritDoc} */ + public AFPDataObjectInfo generateDataObjectInfo( + AFPRendererImageInfo rendererImageInfo) throws IOException { + AFPDataObjectInfo dataObjectInfo = super.generateDataObjectInfo(rendererImageInfo); + + ImageInfo imageInfo = rendererImageInfo.getImageInfo(); + String mimeType = imageInfo.getMimeType(); + if (mimeType != null) { + dataObjectInfo.setMimeType(mimeType); + } + ImageRawStream rawStream = (ImageRawStream) rendererImageInfo.getImage(); + InputStream inputStream = rawStream.createInputStream(); + try { + dataObjectInfo.setData(IOUtils.toByteArray(inputStream)); + } finally { + IOUtils.closeQuietly(inputStream); + } + + int dataHeight = rawStream.getSize().getHeightPx(); + dataObjectInfo.setDataHeight(dataHeight); + + int dataWidth = rawStream.getSize().getWidthPx(); + dataObjectInfo.setDataWidth(dataWidth); + + ImageSize imageSize = rawStream.getSize(); + dataObjectInfo.setDataHeightRes((int) (imageSize.getDpiHorizontal() * 10)); + dataObjectInfo.setDataWidthRes((int) (imageSize.getDpiVertical() * 10)); + + // set object area info + AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); + AFPRendererContext rendererContext + = (AFPRendererContext)rendererImageInfo.getRendererContext(); + AFPInfo afpInfo = rendererContext.getInfo(); + AFPPaintingState paintingState = afpInfo.getPaintingState(); + int resolution = paintingState.getResolution(); + objectAreaInfo.setWidthRes(resolution); + objectAreaInfo.setHeightRes(resolution); + + return dataObjectInfo; + } + +} diff --git a/src/java/org/apache/fop/render/afp/exceptions/FontRuntimeException.java b/src/java/org/apache/fop/render/afp/exceptions/FontRuntimeException.java deleted file mode 100644 index a54e4ad67..000000000 --- a/src/java/org/apache/fop/render/afp/exceptions/FontRuntimeException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.exceptions; - -/** - * A runtime exception for handling fatal errors in processing fonts. - * <p/> - */ -public class FontRuntimeException extends NestedRuntimeException { - - /** - * Constructs a FontRuntimeException with the specified message. - * @param msg the exception mesaage - */ - public FontRuntimeException(String msg) { - super(msg); - } - - /** - * Constructs a FontRuntimeException with the specified message - * wrapping the underlying exception. - * @param msg the exception mesaage - * @param t the underlying exception - */ - public FontRuntimeException(String msg, Throwable t) { - super(msg, t); - } - -} diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java b/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java index 665a77562..6b4bc4eb9 100755 --- a/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java @@ -19,14 +19,13 @@ package org.apache.fop.render.afp.extensions; -import org.apache.fop.apps.FOPException; import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.properties.Property; import org.apache.fop.fo.properties.StringProperty; /** * This class extends the org.apache.fop.fo.StringProperty.Maker inner class - * in order to provide a static property maker. The object faciliates + * in order to provide a static property maker. The object facilitates * extraction of attributes from formatted objects based on the static list * as defined in the AFPElementMapping implementation. * <p/> @@ -58,5 +57,4 @@ public class AFPAttribute extends StringProperty.Maker { } return property; } - }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPElement.java index b8bfa74b6..2fdd32649 100755 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPElement.java @@ -23,6 +23,7 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.extensions.ExtensionAttachment; /** * This class extends the org.apache.fop.extensions.ExtensionObj class. The @@ -45,13 +46,13 @@ public class AFPElement extends AbstractAFPExtensionObject { /** {@inheritDoc} */ protected void startOfNode() throws FOPException { super.startOfNode(); - //if (!AFPElementMapping.NAMESPACE.equals(parent.getNamespaceURI()) - // || !AFPElementMapping.PAGE.equals(parent.getLocalName())) { - // throw new ValidationException(getName() + " must be a child of afp:page."); - //} if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { throw new ValidationException(getName() + " must be a child of fo:simple-page-master."); } } + /** {@inheritDoc} */ + protected ExtensionAttachment instantiateExtensionAttachment() { + return new AFPPageSetup(getName()); + } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java index 216379cc0..c3ba2c43b 100755 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java @@ -19,8 +19,6 @@ package org.apache.fop.render.afp.extensions; -import java.util.HashMap; - import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.FONode; @@ -39,7 +37,7 @@ public class AFPElementMapping extends ElementMapping { public static final String PAGE = "page"; /** page group element */ - public static final String PAGE_GROUP = "page-group"; +// public static final String PAGE_GROUP = "page-group"; /** tag logical element */ public static final String TAG_LOGICAL_ELEMENT = "tag-logical-element"; @@ -53,6 +51,9 @@ public class AFPElementMapping extends ElementMapping { /** NOP */ public static final String NO_OPERATION = "no-operation"; + /** resource information (name, level, dest) */ +// public static final String RESOURCE_INFO = "resource-info"; + /** * The namespace used for AFP extensions */ @@ -69,15 +70,18 @@ public class AFPElementMapping extends ElementMapping { } /** - * Private static synchronized method to set up the element and atribute + * Private static synchronized method to set up the element and attribute * HashMaps, this defines what elements and attributes are extracted. */ protected void initialize() { if (foObjs == null) { - foObjs = new HashMap(); + super.foObjs = new java.util.HashMap(); foObjs.put(PAGE, new AFPPageSetupMaker()); - // foObjs.put(PAGE_GROUP, new AFPMaker()); +// foObjs.put( +// PAGE_GROUP, +// new AFPPageGroupMaker() +// ); foObjs.put( TAG_LOGICAL_ELEMENT, new AFPTagLogicalElementMaker()); @@ -90,8 +94,10 @@ public class AFPElementMapping extends ElementMapping { foObjs.put( NO_OPERATION, new AFPNoOperationMaker()); +// foObjs.put( +// RESOURCE_INFO, +// new AFPResourceInfoMaker()); } - } static class AFPPageSetupMaker extends ElementMapping.Maker { @@ -123,4 +129,16 @@ public class AFPElementMapping extends ElementMapping { return new AFPElement(parent, NO_OPERATION); } } + +// static class AFPResourceInfoMaker extends ElementMapping.Maker { +// public FONode make(FONode parent) { +// return new AFPResourceInfoElement(parent); +// } +// } + +// static class AFPPageGroupMaker extends ElementMapping.Maker { +// public FONode make(FONode parent) { +// return new AFPElement(parent, PAGE_GROUP); +// } +// } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java new file mode 100644 index 000000000..9a8429b00 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id: $ */ + +package org.apache.fop.render.afp.extensions; + +import java.io.Serializable; + +import org.apache.fop.fo.extensions.ExtensionAttachment; +import org.apache.xmlgraphics.util.XMLizable; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * This is the pass-through value object for the AFP extension. + */ +public abstract class AFPExtensionAttachment + implements ExtensionAttachment, Serializable, XMLizable { + private static final long serialVersionUID = 7190606822558332901L; + + /** The category URI for this extension attachment. */ + public static final String CATEGORY = "apache:fop:extensions:afp"; + + /** + * the extension element name + */ + protected String elementName; + + /** + * the extension content + */ + protected String content; + + /** + * the extension name attribute + */ + protected String name; + + /** + * the extension value attribute + */ + protected String value; + + /** + * Default constructor. + * + * @param elementName the name of the afp extension attachment, may be null + */ + public AFPExtensionAttachment(String elementName) { + this.elementName = elementName; + } + + /** @return the name */ + public String getElementName() { + return elementName; + } + + /** + * @return true if this element has a name attribute + */ + protected boolean hasName() { + return name != null; + } + + /** @return the name */ + public String getName() { + return name; + } + + /** + * Sets the name of the setup code object. + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * Sets the value + * @param source The value name to set. + */ + public void setValue(String source) { + this.value = source; + } + + /** {@inheritDoc} */ + public String getCategory() { + return CATEGORY; + } + + /** + * @return the data + */ + public String getContent() { + return content; + } + + /** + * Sets the data + * @param content The byte data to set. + */ + public void setContent(String content) { + this.content = content; + } + + /** + * name attribute + */ + protected static final String ATT_NAME = "name"; + + /** + * value attribute + */ + protected static final String ATT_VALUE = "value"; + + /** {@inheritDoc} */ + public void toSAX(ContentHandler handler) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + if (name != null && name.length() > 0) { + atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); + } + if (value != null && value.length() > 0) { + atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value); + } + handler.startElement(CATEGORY, elementName, elementName, atts); + if (content != null && content.length() > 0) { + char[] chars = content.toCharArray(); + handler.characters(chars, 0, chars.length); + } + handler.endElement(CATEGORY, elementName, elementName); + } +} diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java index 61ad9c1e7..08989c03c 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java @@ -54,7 +54,7 @@ public class AFPExtensionHandler extends DefaultHandler || localName.equals(AFPElementMapping.INCLUDE_PAGE_OVERLAY) || localName.equals(AFPElementMapping.INCLUDE_PAGE_SEGMENT) || localName.equals(AFPElementMapping.PAGE) - || localName.equals(AFPElementMapping.PAGE_GROUP)) { + /*|| localName.equals(AFPElementMapping.PAGE_GROUP)*/) { //handled in endElement } else { handled = false; diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java index 30bc217e7..998ce6921 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java @@ -19,33 +19,10 @@ package org.apache.fop.render.afp.extensions; -import java.io.Serializable; - -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -import org.apache.xmlgraphics.util.XMLizable; - -import org.apache.fop.fo.extensions.ExtensionAttachment; - /** * This is the pass-through value object for the PostScript extension. */ -public class AFPPageSetup implements ExtensionAttachment, Serializable, XMLizable { - - private static final long serialVersionUID = 7190606822558332901L; - - /** The category URI for this extension attachment. */ - public static final String CATEGORY = "apache:fop:extensions:afp"; - - private String elementName; - - private String name; - - private String value; - - private String content; +public class AFPPageSetup extends AFPExtensionAttachment { /** * Default constructor. @@ -53,85 +30,16 @@ public class AFPPageSetup implements ExtensionAttachment, Serializable, XMLizabl * @param elementName the name of the setup code object, may be null */ public AFPPageSetup(String elementName) { - this.elementName = elementName; - } - - /** @return the name */ - public String getElementName() { - return elementName; - } - - /** @return the name */ - public String getName() { - return name; - } - - /** - * Sets the name of the setup code object. - * @param name The name to set. - */ - public void setName(String name) { - this.name = name; + super(elementName); } - /** - * @return the value - */ - public String getValue() { - return value; - } - - /** - * Sets the value - * @param source The value name to set. - */ - public void setValue(String source) { - this.value = source; - } - - /** {@inheritDoc} */ - public String getCategory() { - return CATEGORY; - } + private static final long serialVersionUID = -549941295384013190L; /** - * @return the data + * {@inheritDoc} */ - public String getContent() { - return content; - } - - /** - * Sets the data - * @param content The byte data to set. - */ - public void setContent(String content) { - this.content = content; - } - - /** {@inheritDoc} */ public String toString() { return "AFPPageSetup(element-name=" + getElementName() + " name=" + getName() + " value=" + getValue() + ")"; } - - private static final String ATT_NAME = "name"; - private static final String ATT_VALUE = "value"; - - /** {@inheritDoc} */ - public void toSAX(ContentHandler handler) throws SAXException { - AttributesImpl atts = new AttributesImpl(); - if (name != null && name.length() > 0) { - atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); - } - if (value != null && value.length() > 0) { - atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value); - } - handler.startElement(CATEGORY, elementName, elementName, atts); - if (content != null && content.length() > 0) { - char[] chars = content.toCharArray(); - handler.characters(chars, 0, chars.length); - } - handler.endElement(CATEGORY, elementName, elementName); - } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java index 4971928f8..d167a8d4b 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java @@ -23,9 +23,10 @@ import org.apache.fop.apps.FOPException; import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode; import org.apache.fop.fo.ValidationException; +import org.apache.fop.fo.extensions.ExtensionAttachment; /** - * Extension element for fox:ps-page-setup-code. + * Extension element for afp:ps-page-setup-code. */ public class AFPPageSetupElement extends AbstractAFPExtensionObject { @@ -45,4 +46,10 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } } + /** + * {@inheritDoc} + */ + protected ExtensionAttachment instantiateExtensionAttachment() { + return new AFPPageSetup(this.name); + } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java index a92687aab..c0e9c2c89 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java +++ b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java @@ -35,11 +35,14 @@ import org.apache.fop.fo.extensions.ExtensionAttachment; public abstract class AbstractAFPExtensionObject extends FONode { /** - * AFP setup code + * the AFP extension attachment */ - private AFPPageSetup setupCode; + protected AFPExtensionAttachment extensionAttachment; - private String name; + /** + * the element name of this extension + */ + protected String name; /** * @see org.apache.fop.fo.FONode#FONode(FONode) @@ -49,10 +52,11 @@ public abstract class AbstractAFPExtensionObject extends FONode { public AbstractAFPExtensionObject(FONode parent, String name) { super(parent); this.name = name; - this.setupCode = new AFPPageSetup(name); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ protected void validateChildNode(Locator loc, String nsURI, String localName) throws ValidationException { if (FO_URI.equals(nsURI)) { @@ -60,60 +64,85 @@ public abstract class AbstractAFPExtensionObject extends FONode { } } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ protected void characters(char[] data, int start, int length, - PropertyList pList, Locator locator) { - setupCode.setContent(new String(data, start, length)); + PropertyList pList, Locator locator) throws FOPException { + ((AFPExtensionAttachment)getExtensionAttachment()).setContent( + new String(data, start, length)); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public String getNamespaceURI() { return AFPElementMapping.NAMESPACE; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public String getNormalNamespacePrefix() { return AFPElementMapping.NAMESPACE_PREFIX; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList propertyList) throws FOPException { - String name = attlist.getValue("name"); - if (name != null && name.length() > 0) { - setupCode.setName(name); + getExtensionAttachment(); + String attr = attlist.getValue("name"); + if (attr != null && attr.length() > 0) { + extensionAttachment.setName(attr); } else { throw new FOPException(elementName + " must have a name attribute."); } if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) { - name = attlist.getValue("src"); - if (name != null && name.length() > 0) { - setupCode.setValue(name); + attr = attlist.getValue("src"); + if (attr != null && attr.length() > 0) { + extensionAttachment.setValue(attr); } else { throw new FOPException(elementName + " must have a src attribute."); } } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) { - name = attlist.getValue("value"); - if (name != null && name.length() > 0) { - setupCode.setValue(name); + attr = attlist.getValue("value"); + if (attr != null && attr.length() > 0) { + extensionAttachment.setValue(attr); } else { throw new FOPException(elementName + " must have a value attribute."); } } } - - /** {@inheritDoc} */ + + /** + * {@inheritDoc} + */ protected void endOfNode() throws FOPException { super.endOfNode(); } - /** {@inheritDoc} */ + /** + * Instantiates extension attachment object + * @return extension attachment + */ + protected abstract ExtensionAttachment instantiateExtensionAttachment(); + + /** + * {@inheritDoc} + */ public ExtensionAttachment getExtensionAttachment() { - return this.setupCode; + if (extensionAttachment == null) { + this.extensionAttachment = (AFPExtensionAttachment)instantiateExtensionAttachment(); + } + return this.extensionAttachment; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ public String getLocalName() { return name; } diff --git a/src/java/org/apache/fop/render/afp/fonts/AFPFont.java b/src/java/org/apache/fop/render/afp/fonts/AFPFont.java deleted file mode 100644 index 2819cf12c..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/AFPFont.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; -import java.util.Map; -import java.util.Set; - -import org.apache.fop.fonts.FontType; -import org.apache.fop.fonts.Typeface; - - -/** - * All implementations of AFP fonts should extend this base class, - * the object implements the FontMetrics information. - * <p/> - */ -public abstract class AFPFont extends Typeface { - - /** The font name */ - protected String name; - - /** - * Constructor for the base font requires the name. - * @param name the name of the font - */ - public AFPFont(String name) { - this.name = name; - - } - - /** {@inheritDoc} */ - public String getFontName() { - return this.name; - } - - /** {@inheritDoc} */ - public String getEmbedFontName() { - return this.name; - } - - /** {@inheritDoc} */ - public String getFullName() { - return getFontName(); - } - - /** {@inheritDoc} */ - public Set getFamilyNames() { - Set s = new java.util.HashSet(); - s.add(this.name); - return s; - } - - /** - * Returns the type of the font. - * @return the font type - */ - public FontType getFontType() { - return FontType.OTHER; - } - - /** - * Indicates if the font has kerning information. - * @return True, if kerning is available. - */ - public boolean hasKerningInfo() { - return false; - } - - /** - * Returns the kerning map for the font. - * @return the kerning map - */ - public Map getKerningInfo() { - return null; - } - - /** - * Returns the character set for a given size - * @param size the font size - * @return the character set object - */ - public abstract CharacterSet getCharacterSet(int size); - - /** - * Determines whether this font contains a particular character/glyph. - * @param c character to check - * @return True if the character is supported, False otherwise - */ - public boolean hasChar(char c) { - return true; - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/fonts/AFPFontCollection.java b/src/java/org/apache/fop/render/afp/fonts/AFPFontCollection.java deleted file mode 100644 index 03b5580cf..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/AFPFontCollection.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import java.util.Iterator; -import java.util.List; - -import org.apache.fop.events.EventBroadcaster; -import org.apache.fop.fonts.Font; -import org.apache.fop.fonts.FontCollection; -import org.apache.fop.fonts.FontInfo; -import org.apache.fop.fonts.FontTriplet; -import org.apache.fop.fonts.base14.Courier; -import org.apache.fop.fonts.base14.Helvetica; -import org.apache.fop.fonts.base14.TimesRoman; -import org.apache.fop.render.afp.AFPEventProducer; - -/** - * A base collection of AFP fonts - */ -public class AFPFontCollection implements FontCollection { - - private EventBroadcaster eventBroadcaster; - private List/*<EmbedFontInfo>*/ embedFontInfoList; - - /** - * Main constructor - * - * @param eventBroadcaster the event broadcaster - * @param embedFontInfoList the embed font info list - */ - public AFPFontCollection(EventBroadcaster eventBroadcaster, - List/*<EmbedFontInfo>*/ embedFontInfoList) { - this.eventBroadcaster = eventBroadcaster; - this.embedFontInfoList = embedFontInfoList; - } - - /** {@inheritDoc} */ - public int setup(int start, FontInfo fontInfo) { - int num = 1; - if (embedFontInfoList != null && embedFontInfoList.size() > 0) { - for (Iterator it = embedFontInfoList.iterator(); it.hasNext();) { - AFPFontInfo afi = (AFPFontInfo)it.next(); - AFPFont bf = (AFPFont)afi.getAFPFont(); - for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) { - FontTriplet ft = (FontTriplet)it2.next(); - fontInfo.addFontProperties("F" + num, ft.getName() - , ft.getStyle(), ft.getWeight()); - fontInfo.addMetrics("F" + num, bf); - num++; - } - } - } else { - AFPEventProducer eventProducer = AFPEventProducer.Provider.get(eventBroadcaster); - eventProducer.warnDefaultFontSetup(this); - } - if (fontInfo.fontLookup("sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL) == null) { - CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZH200 ", - 1, new Helvetica()); - AFPFont bf = new OutlineFont("Helvetica", cs); - fontInfo.addFontProperties( - "F" + num, "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); - fontInfo.addMetrics("F" + num, bf); - num++; - } - if (fontInfo.fontLookup("serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL) == null) { - CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZN200 ", - 1, new TimesRoman()); - AFPFont bf = new OutlineFont("Helvetica", cs); - fontInfo.addFontProperties("F" + num, "serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); - fontInfo.addMetrics("F" + num, bf); - num++; - } - if (fontInfo.fontLookup("monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL) == null) { - CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZ4200 ", - 1, new Courier()); - AFPFont bf = new OutlineFont("Helvetica", cs); - fontInfo.addFontProperties( - "F" + num, "monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); - fontInfo.addMetrics("F" + num, bf); - num++; - } - if (fontInfo.fontLookup("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL) == null) { - FontTriplet ft = fontInfo.fontLookup( - "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); - fontInfo.addFontProperties( - fontInfo.getInternalFontKey(ft), "any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); - num++; - } - return num; - } - -} diff --git a/src/java/org/apache/fop/render/afp/fonts/AFPFontInfo.java b/src/java/org/apache/fop/render/afp/fonts/AFPFontInfo.java deleted file mode 100644 index 42f333a66..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/AFPFontInfo.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import java.util.List; - -/** - * FontInfo contains meta information on fonts - */ -public class AFPFontInfo { - - private AFPFont font; - private List fontTriplets; - - /** - * Main constructor - * @param afpFont The AFP Font - * @param fontTriplets List of font triplets to associate with this font - */ - public AFPFontInfo(AFPFont afpFont, List fontTriplets) { - this.font = afpFont; - this.fontTriplets = fontTriplets; - } - - /** - * Returns the afp font - * @return the afp font - */ - public AFPFont getAFPFont() { - return font; - } - - /** - * Returns the list of font triplets associated with this font. - * @return List of font triplets - */ - public List getFontTriplets() { - return fontTriplets; - } - -} - diff --git a/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java b/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java deleted file mode 100644 index 0c190738c..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/AFPFontReader.java +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.afp.modca.AFPConstants; -import org.apache.fop.render.afp.tools.StructuredFieldReader; - -/** - * The AFPFontReader is responsible for reading the font attributes from binary - * code page files and the character set metric files. In IBM font structure, a - * code page maps each character of text to the characters in a character set. - * Each character is translated into a code point. When the character is - * printed, each code point is matched to a character ID on the code page - * specified. The character ID is then matched to the image (raster pattern or - * outline pattern) of the character in the character set specified. The image - * in the character set is the image that is printed in the document. To be a - * valid code page for a particular character set, all character IDs in the code - * page must be included in that character set. <p/>This class will read the - * font information from the binary code page files and character set metric - * files in order to determine the correct metrics to use when rendering the - * formatted object. <p/> - * - * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a> - */ -public final class AFPFontReader { - - /** - * Static logging instance - */ - protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts"); - - /** - * Template used to convert lists to arrays. - */ - private static final CharacterSetOrientation[] EMPTY_CSO_ARRAY = new CharacterSetOrientation[0]; - - /** Codepage MO:DCA structured field. */ - private static final byte[] CODEPAGE_SF = new byte[] { - (byte) 0xD3, (byte) 0xA8, (byte) 0x87}; - - /** Character table MO:DCA structured field. */ - private static final byte[] CHARACTER_TABLE_SF = new byte[] { - (byte) 0xD3, (byte) 0x8C, (byte) 0x87}; - - /** Font control MO:DCA structured field. */ - private static final byte[] FONT_CONTROL_SF = new byte[] { - (byte) 0xD3, (byte) 0xA7, (byte) 0x89 }; - - /** Font orientation MO:DCA structured field. */ - private static final byte[] FONT_ORIENTATION_SF = new byte[] { - (byte) 0xD3, (byte) 0xAE, (byte) 0x89 }; - - /** Font position MO:DCA structured field. */ - private static final byte[] FONT_POSITION_SF = new byte[] { - (byte) 0xD3, (byte) 0xAC, (byte) 0x89 }; - - /** Font index MO:DCA structured field. */ - private static final byte[] FONT_INDEX_SF = new byte[] { - (byte) 0xD3, (byte) 0x8C, (byte) 0x89 }; - - /** - * The conversion factor to millipoints for 240 dpi - */ - private static final int FOP_100_DPI_FACTOR = 1; - - /** - * The conversion factor to millipoints for 240 dpi - */ - private static final int FOP_240_DPI_FACTOR = 300000; - - /** - * The conversion factor to millipoints for 300 dpi - */ - private static final int FOP_300_DPI_FACTOR = 240000; - - /** - * The encoding to use to convert from EBCIDIC to ASCII - */ - private static final String ASCII_ENCODING = "UTF8"; - - /** - * The collection of code pages - */ - private final Map/*<String, Map<String, String>>*/ codePages - = new java.util.HashMap/*<String, Map<String, String>>*/(); - - /** - * Returns an InputStream to a given file path and filename - * - * @param path the file path - * @param filename the file name - * @return an inputStream - * - * @throws IOException in the event that an I/O exception of some sort has occurred - */ - private InputStream openInputStream(String path, String filename) throws IOException { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader == null) { - classLoader = AFPFontReader.class.getClassLoader(); - } - - URL url = classLoader.getResource(path); - - if (url == null) { - try { - File file = new File(path); - url = file.toURI().toURL(); - if (url == null) { - String msg = "file not found " + filename + " in classpath: " + path; - log.error(msg); - throw new FileNotFoundException(msg); - } - } catch (MalformedURLException ex) { - String msg = "file not found " + filename + " in classpath: " + path; - log.error(msg); - throw new FileNotFoundException(msg); - } - } - - File directory = new File(url.getPath()); - if (!directory.canRead()) { - String msg = "Failed to read directory " + url.getPath(); - log.error(msg); - throw new FileNotFoundException(msg); - } - - final String filterpattern = filename.trim(); - FilenameFilter filter = new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith(filterpattern); - } - }; - - File[] files = directory.listFiles(filter); - - if (files.length < 1) { - String msg = "file search for " + filename + " located " - + files.length + " files"; - log.error(msg); - throw new FileNotFoundException(msg); - } else if (files.length > 1) { - String msg = "file search for " + filename + " located " - + files.length + " files"; - log.warn(msg); - } - - InputStream inputStream = files[0].toURI().toURL().openStream(); - - if (inputStream == null) { - String msg = "AFPFontReader:: getInputStream():: file not found for " + filename; - log.error(msg); - throw new FileNotFoundException(msg); - } - - return inputStream; - } - - /** - * Closes the inputstream - * - * @param inputStream the inputstream to close - */ - private void closeInputStream(InputStream inputStream) { - try { - if (inputStream != null) { - inputStream.close(); - } - } catch (Exception ex) { - // Lets log at least! - log.error(ex.getMessage()); - } - } - - /** - * Load the font details and metrics into the CharacterSetMetric object, - * this will use the actual afp code page and character set files to load - * the object with the necessary metrics. - * - * @param characterSet the CharacterSetMetric object to populate - * @throws IOException if an I/O exception of some sort has occurred. - */ - public void loadCharacterSetMetric(CharacterSet characterSet) throws IOException { - - InputStream inputStream = null; - - try { - - /** - * Get the code page which contains the character mapping - * information to map the unicode character id to the graphic - * chracter global identifier. - */ - String codePageId = new String(characterSet.getCodePage()); - String path = characterSet.getPath(); - - Map/*<String,String>*/ codePage = (Map/*<String,String>*/)codePages.get(codePageId); - - if (codePage == null) { - codePage = loadCodePage(codePageId, characterSet.getEncoding(), path); - codePages.put(codePageId, codePage); - } - - /** - * Load the character set metric information, no need to cache this - * information as it should be cached by the objects that wish to - * load character set metric information. - */ - final String characterSetName = characterSet.getName(); - - inputStream = openInputStream(path, characterSetName); - - StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); - - // Process D3A789 Font Control - FontControl fontControl = processFontControl(structuredFieldReader); - - if (fontControl != null) { - //process D3AE89 Font Orientation - CharacterSetOrientation[] characterSetOrientations - = processFontOrientation(structuredFieldReader); - - int dpi = fontControl.getDpi(); - - //process D3AC89 Font Position - processFontPosition(structuredFieldReader, characterSetOrientations, dpi); - - //process D38C89 Font Index (per orientation) - for (int i = 0; i < characterSetOrientations.length; i++) { - processFontIndex(structuredFieldReader, - characterSetOrientations[i], codePage, dpi); - characterSet.addCharacterSetOrientation(characterSetOrientations[i]); - } - } else { - throw new IOException( - "Failed to read font control structured field in character set " - + characterSetName); - } - - } finally { - closeInputStream(inputStream); - } - - } - - /** - * Load the code page information from the appropriate file. The file name - * to load is determined by the code page name and the file extension 'CDP'. - * - * @param codePage - * the code page identifier - * @param encoding - * the encoding to use for the character decoding - * @returns a code page mapping - */ - private Map/*<String,String>*/ loadCodePage(String codePage, String encoding, - String path) throws IOException { - - // Create the HashMap to store code page information - Map/*<String,String>*/ codePages = new java.util.HashMap/*<String,String>*/(); - - InputStream inputStream = null; - try { - inputStream = openInputStream(path, codePage.trim()); - - StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); - byte[] data = structuredFieldReader.getNext(CHARACTER_TABLE_SF); - - int position = 0; - byte[] gcgiBytes = new byte[8]; - byte[] charBytes = new byte[1]; - - // Read data, ignoring bytes 0 - 2 - for (int index = 3; index < data.length; index++) { - if (position < 8) { - // Build the graphic character global identifier key - gcgiBytes[position] = data[index]; - position++; - } else if (position == 9) { - position = 0; - // Set the character - charBytes[0] = data[index]; - String gcgiString = new String(gcgiBytes, - AFPConstants.EBCIDIC_ENCODING); - String charString = new String(charBytes, encoding); -// int value = charString.charAt(0); - codePages.put(gcgiString, charString); - } else { - position++; - } - } - } finally { - closeInputStream(inputStream); - } - - return codePages; - } - - /** - * Process the font control details using the structured field reader. - * - * @param structuredFieldReader - * the structured field reader - */ - private FontControl processFontControl(StructuredFieldReader structuredFieldReader) - throws IOException { - - byte[] fncData = structuredFieldReader.getNext(FONT_CONTROL_SF); - -// int position = 0; - FontControl fontControl = null; - if (fncData != null) { - fontControl = new FontControl(); - - if (fncData[7] == (byte) 0x02) { - fontControl.setRelative(true); - } - - int dpi = (((fncData[9] & 0xFF) << 8) + (fncData[10] & 0xFF)) / 10; - - fontControl.setDpi(dpi); - } - return fontControl; - } - - /** - * Process the font orientation details from using the structured field - * reader. - * - * @param structuredFieldReader - * the structured field reader - */ - private CharacterSetOrientation[] processFontOrientation( - StructuredFieldReader structuredFieldReader) throws IOException { - - byte[] data = structuredFieldReader.getNext(FONT_ORIENTATION_SF); - - int position = 0; - byte[] fnoData = new byte[26]; - - List orientations = new java.util.ArrayList(); - - // Read data, ignoring bytes 0 - 2 - for (int index = 3; index < data.length; index++) { - // Build the font orientation record - fnoData[position] = data[index]; - position++; - - if (position == 26) { - - position = 0; - - int orientation = 0; - - switch (fnoData[2]) { - case 0x00: - orientation = 0; - break; - case 0x2D: - orientation = 90; - break; - case 0x5A: - orientation = 180; - break; - case (byte) 0x87: - orientation = 270; - break; - default: - System.out.println("ERROR: Oriantation"); - } - - CharacterSetOrientation cso = new CharacterSetOrientation( - orientation); - orientations.add(cso); - - } - } - - return (CharacterSetOrientation[]) orientations - .toArray(EMPTY_CSO_ARRAY); - } - - /** - * Populate the CharacterSetOrientation object in the suplied array with the - * font position details using the supplied structured field reader. - * - * @param structuredFieldReader - * the structured field reader - * @param characterSetOrientations - * the array of CharacterSetOrientation objects - */ - private void processFontPosition(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation[] characterSetOrientations, int dpi) throws IOException { - - byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF); - - int position = 0; - byte[] fpData = new byte[26]; - - int characterSetOrientationIndex = 0; - int fopFactor = 0; - - switch (dpi) { - case 100: - fopFactor = FOP_100_DPI_FACTOR; - break; - case 240: - fopFactor = FOP_240_DPI_FACTOR; - break; - case 300: - fopFactor = FOP_300_DPI_FACTOR; - break; - default: - String msg = "Unsupported font resolution of " + dpi + " dpi."; - log.error(msg); - throw new IOException(msg); - } - - // Read data, ignoring bytes 0 - 2 - for (int index = 3; index < data.length; index++) { - if (position < 22) { - // Build the font orientation record - fpData[position] = data[index]; - } else if (position == 22) { - - position = 0; - - CharacterSetOrientation characterSetOrientation - = characterSetOrientations[characterSetOrientationIndex]; - - int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 0xFF); - int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 0xFF); - int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 0xFF); - int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 0xFF); - - dscHeight = dscHeight * -1; - - characterSetOrientation.setXHeight(xHeight * fopFactor); - characterSetOrientation.setCapHeight(capHeight * fopFactor); - characterSetOrientation.setAscender(ascHeight * fopFactor); - characterSetOrientation.setDescender(dscHeight * fopFactor); - - characterSetOrientationIndex++; - - fpData[position] = data[index]; - - } - - position++; - } - - } - - /** - * Process the font index details for the character set orientation. - * - * @param structuredFieldReader - * the structured field reader - * @param cso - * the CharacterSetOrientation object to populate - * @param codepage - * the map of code pages - */ - private void processFontIndex(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation cso, Map/*<String,String>*/ codepage, int dpi) - throws IOException { - - byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF); - - int fopFactor = 0; - - switch (dpi) { - case 100: - fopFactor = FOP_100_DPI_FACTOR; - break; - case 240: - fopFactor = FOP_240_DPI_FACTOR; - break; - case 300: - fopFactor = FOP_300_DPI_FACTOR; - break; - default: - String msg = "Unsupported font resolution of " + dpi + " dpi."; - log.error(msg); - throw new IOException(msg); - } - - int position = 0; - - byte[] gcgid = new byte[8]; - byte[] fiData = new byte[20]; - - int lowest = 255; - int highest = 0; - - // Read data, ignoring bytes 0 - 2 - for (int index = 3; index < data.length; index++) { - if (position < 8) { - gcgid[position] = data[index]; - position++; - } else if (position < 27) { - fiData[position - 8] = data[index]; - position++; - } else if (position == 27) { - - fiData[position - 8] = data[index]; - - position = 0; - - String gcgiString = new String(gcgid, AFPConstants.EBCIDIC_ENCODING); - - String idx = (String) codepage.get(gcgiString); - - if (idx != null) { - - int cidx = idx.charAt(0); - int width = ((fiData[0] & 0xFF) << 8) + (fiData[1] & 0xFF); - - if (cidx < lowest) { - lowest = cidx; - } - - if (cidx > highest) { - highest = cidx; - } - - int a = (width * fopFactor); - - cso.setWidth(cidx, a); - - } - - } - } - - cso.setFirstChar(lowest); - cso.setLastChar(highest); - - } - - private class FontControl { - - private int dpi; - - private boolean isRelative = false; - - public int getDpi() { - return dpi; - } - - public void setDpi(int i) { - dpi = i; - } - - public boolean isRelative() { - return isRelative; - } - - public void setRelative(boolean b) { - isRelative = b; - } - } - -} diff --git a/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java deleted file mode 100644 index f7680b15c..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/CharacterSet.java +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.afp.modca.AFPConstants; -import org.apache.fop.render.afp.tools.StringUtils; - -/** - * The IBM Font Object Content Architecture (FOCA) supports presentation - * of character shapes by defining their characteristics, which include - * font description information for identifying the characters, font metric - * information for positioning the characters, and character shape information - * for presenting the character images. - * <p/> - * Presenting a graphic character on a presentation surface requires - * information on the rotation and position of character on the physical - * or logical page. - * <p/> - * This class proivdes font metric information for a particular font - * as identified by the character set name. This information is obtained - * directly from the AFP font files which must be installed in the path - * specified in the afp-fonts xml definition file. - * <p/> - */ -public class CharacterSet { - - /** Static logging instance */ - protected static final Log log = LogFactory.getLog(CharacterSet.class.getName()); - - /** default codepage */ - protected static final String DEFAULT_CODEPAGE = "T1V10500"; - - /** default encoding */ - protected static final String DEFAULT_ENCODING = "Cp500"; - - private static final int MAX_NAME_LEN = 8; - - - /** The code page to which the character set relates */ - protected String codePage; - - /** The encoding used for the code page */ - protected String encoding; - - /** The character set relating to the font */ - protected String name; - - /** The path to the installed fonts */ - protected String path; - - /** Indicator as to whether to metrics have been loaded */ - private boolean isMetricsLoaded = false; - - /** The current orientation (currently only 0 is supported by FOP) */ - private final String currentOrientation = "0"; - - /** The collection of objects for each orientation */ - private Map characterSetOrientations = null; - - /** - * Constructor for the CharacterSetMetric object, the character set is used - * to load the font information from the actual AFP font. - * - * @param codePage the code page identifier - * @param encoding the encoding of the font - * @param name the character set name - * @param path the path to the installed afp fonts - */ - public CharacterSet(String codePage, String encoding, String name, String path) { - if (name.length() > MAX_NAME_LEN) { - String msg = "Character set name '" + name + "' must be a maximum of " - + MAX_NAME_LEN + " characters"; - log.error("Constructor:: " + msg); - throw new IllegalArgumentException(msg); - } - - if (name.length() < MAX_NAME_LEN) { - this.name = StringUtils.rpad(name, ' ', MAX_NAME_LEN); - } else { - this.name = name; - } - this.codePage = codePage; - this.encoding = encoding; - this.path = path; - - this.characterSetOrientations = new java.util.HashMap(4); - } - - /** - * Add character set metric information for the different orientations - * - * @param cso the metrics for the orientation - */ - public void addCharacterSetOrientation(CharacterSetOrientation cso) { - characterSetOrientations.put( - String.valueOf(cso.getOrientation()), - cso); - } - - /** - * Ascender height is the distance from the character baseline to the - * top of the character box. A negative ascender height signifies that - * all of the graphic character is below the character baseline. For - * a character rotation other than 0, ascender height loses its - * meaning when the character is lying on its side or is upside down - * with respect to normal viewing orientation. For the general case, - * Ascender Height is the characters most positive y-axis value. - * For bounded character boxes, for a given character having an - * ascender, ascender height and baseline offset are equal. - * - * @return the ascender value in millipoints - */ - public int getAscender() { - load(); - return getCharacterSetOrientation().getAscender(); - } - - /** - * Cap height is the average height of the uppercase characters in - * a font. This value is specified by the designer of a font and is - * usually the height of the uppercase M. - * - * @return the cap height value in millipoints - */ - public int getCapHeight() { - load(); - return getCharacterSetOrientation().getCapHeight(); - } - - /** - * Descender depth is the distance from the character baseline to - * the bottom of a character box. A negative descender depth signifies - * that all of the graphic character is above the character baseline. - * - * @return the descender value in millipoints - */ - public int getDescender() { - load(); - return getCharacterSetOrientation().getDescender(); - } - - /** - * Returns the first character in the character set - * - * @return the first character in the character set - */ - public int getFirstChar() { - load(); - return getCharacterSetOrientation().getFirstChar(); - } - - /** - * Returns the last character in the character set - * - * @return the last character in the character set - */ - public int getLastChar() { - load(); - return getCharacterSetOrientation().getLastChar(); - } - - /** - * Returns the path where the font resources are installed - * - * @return the path where the font resources are installed - */ - public String getPath() { - return path; - } - - /** - * Get the width (in 1/1000ths of a point size) of all characters - * - * @return the widths of all characters - */ - public int[] getWidths() { - load(); - return getCharacterSetOrientation().getWidths(); - } - - /** - * XHeight refers to the height of the lower case letters above the baseline. - * - * @return the typical height of characters - */ - public int getXHeight() { - load(); - return getCharacterSetOrientation().getXHeight(); - } - - /** - * Get the width (in 1/1000ths of a point size) of the character - * identified by the parameter passed. - * - * @param character the character from which the width will be calculated - * @return the width of the character - */ - public int getWidth(int character) { - load(); - return getCharacterSetOrientation().getWidth(character); - } - - /** - * Lazy creation of the character metrics, the afp font file will only - * be processed on a method call requiring the metric information. - */ - private void load() { - if (!isMetricsLoaded) { - AFPFontReader afpFontReader = new AFPFontReader(); - try { - afpFontReader.loadCharacterSetMetric(this); - isMetricsLoaded = true; - } catch (IOException e) { - String msg = "Failed to load the character set metrics for code page " + codePage; - log.error(msg); - throw new RuntimeException(e.getMessage()); - } - } - } - - /** - * Returns the AFP character set identifier - * - * @return the AFP character set identifier - */ - public String getName() { - return name; - } - - /** - * Returns the AFP character set identifier as a byte array - * - * @return the AFP character set identifier as a byte array - */ - public byte[] getNameBytes() { - byte[] nameBytes = null; - try { - nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - } catch (UnsupportedEncodingException usee) { - nameBytes = name.getBytes(); - log.warn( - "UnsupportedEncodingException translating the name " + name); - } - return nameBytes; - } - - /** - * Returns the AFP code page identifier - * - * @return the AFP code page identifier - */ - public String getCodePage() { - return codePage; - } - - /** - * Returns the AFP code page encoding - * - * @return the AFP code page encoding - */ - public String getEncoding() { - return encoding; - } - - /** - * Helper method to return the current CharacterSetOrientation, note - * that FOP does not yet implement the "reference-orientation" - * attribute therefore we always use the orientation zero degrees, - * Other orientation information is captured for use by a future - * implementation (whenever FOP implement the mechanism). This is also - * the case for landscape prints which use an orientation of 270 degrees, - * in 99.9% of cases the font metrics will be the same as the 0 degrees - * therefore the implementation currently will always use 0 degrees. - * - * @return characterSetOrentation The current orientation metrics. - */ - private CharacterSetOrientation getCharacterSetOrientation() { - CharacterSetOrientation c - = (CharacterSetOrientation) characterSetOrientations.get(currentOrientation); - return c; - } - - /** - * Map a Unicode character to a code point in the font. - * The code tables are already converted to Unicode therefore - * we can use the identity mapping. - * - * @param c character to map - * @return the mapped character - */ - public char mapChar(char c) { - return c; - } - -} diff --git a/src/java/org/apache/fop/render/afp/fonts/CharacterSetOrientation.java b/src/java/org/apache/fop/render/afp/fonts/CharacterSetOrientation.java deleted file mode 100644 index e13029717..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/CharacterSetOrientation.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -/** - * The IBM Font Object Content Architecture (FOCA) supports presentation - * of character shapes by defining their characteristics, which include - * Font-Description information for identifying the characters, Font-Metric - * information for positioning the characters, and Character-Shape - * information for presenting the character images. - * - * Presenting a graphic character on a presentation surface requires - * that you communicate this information clearly to rotate and position - * characters correctly on the physical or logical page. - * - * This class provides font metric information for a particular font - * as by the orientation. - * - * This information is obtained directly from the AFP font files which must - * be installed in the classpath under in the location specified by the path - * attribute in the afp-font.xml file. - * <p/> - */ -public class CharacterSetOrientation { - - /** - * The code page to which the character set relates - */ - private String codePage; - - /** - * The encoding used for the code page - */ - private String encoding; - - /** - * The ascender height for the character set - */ - private int ascender; - - /** - * The descender depth for the character set - */ - private int descender; - - /** - * The height of capital letters - */ - private int capHeight; - - /** - * The characters in the charcater set - */ - private int[] chars = new int[256]; - - /** - * The height of lowercase letters - */ - private int xHeight; - - /** - * The first character - */ - private int firstChar; - - /** - * The last character - */ - private int lastChar; - - - /** - * The character set orientation - */ - private int orientation = 0; - - /** - * Constructor for the CharacterSetOrientation, the orientation is - * expressed as the degrees rotation (i.e 0, 90, 180, 270) - * @param orientation the character set orientation - */ - public CharacterSetOrientation(int orientation) { - this.orientation = orientation; - } - - /** - * Ascender height is the distance from the character baseline to the - * top of the character box. A negative ascender height signifies that - * all of the graphic character is below the character baseline. For - * a character rotation other than 0, ascender height loses its - * meaning when the character is lying on its side or is upside down - * with respect to normal viewing orientation. For the general case, - * Ascender Height is the character�s most positive y-axis value. - * For bounded character boxes, for a given character having an - * ascender, ascender height and baseline offset are equal. - * @return the ascender value in millipoints - */ - public int getAscender() { - return ascender; - } - - /** - * Cap height is the average height of the uppercase characters in - * a font. This value is specified by the designer of a font and is - * usually the height of the uppercase M. - * @return the cap height value in millipoints - */ - public int getCapHeight() { - return capHeight; - } - - /** - * Descender depth is the distance from the character baseline to - * the bottom of a character box. A negative descender depth signifies - * that all of the graphic character is above the character baseline. - * @return the descender value in millipoints - */ - public int getDescender() { - return descender; - } - - /** - * The first character in the character set - * @return the first character - */ - public int getFirstChar() { - return firstChar; - } - - /** - * The last character in the character set - * @return the last character - */ - public int getLastChar() { - return lastChar; - } - - /** - * The orientation for these metrics in the character set - * @return the orientation - */ - public int getOrientation() { - return orientation; - } - - /** - * Get the width (in 1/1000ths of a point size) of all characters - * in this character set. - * @return the widths of all characters - */ - public int[] getWidths() { - int arr[] = new int[(getLastChar() - getFirstChar()) + 1]; - System.arraycopy(chars, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1); - return arr; - } - - /** - * XHeight refers to the height of the lower case letters above - * the baseline. - * @return heightX the typical height of characters - */ - public int getXHeight() { - return xHeight; - } - - /** - * Get the width (in 1/1000ths of a point size) of the character - * identified by the parameter passed. - * @param characterIndex the character to evaluate - * @return the widths of the character - */ - public int getWidth(int characterIndex) { - if (characterIndex >= chars.length) { - throw new IllegalArgumentException("Invalid character index: " - + characterIndex + ", maximum is " + (chars.length - 1)); - } - return chars[characterIndex]; - } - - /** - * Ascender height is the distance from the character baseline to the - * top of the character box. A negative ascender height signifies that - * all of the graphic character is below the character baseline. For - * a character rotation other than 0, ascender height loses its - * meaning when the character is lying on its side or is upside down - * with respect to normal viewing orientation. For the general case, - * Ascender Height is the character�s most positive y-axis value. - * For bounded character boxes, for a given character having an - * ascender, ascender height and baseline offset are equal. - * @param ascender the ascender to set - */ - public void setAscender(int ascender) { - this.ascender = ascender; - } - - /** - * Cap height is the average height of the uppercase characters in - * a font. This value is specified by the designer of a font and is - * usually the height of the uppercase M. - * @param capHeight the cap height to set - */ - public void setCapHeight(int capHeight) { - this.capHeight = capHeight; - } - - /** - * Descender depth is the distance from the character baseline to - * the bottom of a character box. A negative descender depth signifies - * that all of the graphic character is above the character baseline. - * @param descender the descender value in millipoints - */ - public void setDescender(int descender) { - this.descender = descender; - } - - /** - * The first character in the character set - * @param firstChar the first character - */ - public void setFirstChar(int firstChar) { - this.firstChar = firstChar; - } - - /** - * The last character in the character set - * @param lastChar the last character - */ - public void setLastChar(int lastChar) { - this.lastChar = lastChar; - } - - /** - * Set the width (in 1/1000ths of a point size) of the character - * identified by the parameter passed. - * @param character the character for which the width is being set - * @param width the widths of the character - */ - public void setWidth(int character, int width) { - - if (character >= chars.length) { - // Increase the size of the array if necessary - int arr[] = new int[(character - firstChar) + 1]; - System.arraycopy(chars, 0, arr, 0, chars.length); - chars = arr; - } - chars[character] = width; - - } - - /** - * XHeight refers to the height of the lower case letters above - * the baseline. - * @param xHeight the typical height of characters - */ - public void setXHeight(int xHeight) { - this.xHeight = xHeight; - } -} diff --git a/src/java/org/apache/fop/render/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/render/afp/fonts/FopCharacterSet.java deleted file mode 100644 index d5beb5a33..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/FopCharacterSet.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import org.apache.fop.fonts.Typeface; - -/** - * A Character set for a normal FOP font<p/> - */ -public class FopCharacterSet extends CharacterSet { - - /** The character set for this font */ - private Typeface charSet = null; - private int size = 0; - - /** - * Constructor for the CharacterSetMetric object, the character set is used - * to load the font information from the actual AFP font. - * @param codePage the code page identifier - * @param encoding the encoding of the font - * @param name the character set name - * @param size the font size - * @param charSet the fop character set - */ - public FopCharacterSet( - String codePage, - String encoding, - String name, - int size, - Typeface charSet) { - - super(codePage, encoding, name, null); - this.charSet = charSet; - this.size = size * 1000; - } - - /** - * Ascender height is the distance from the character baseline to the - * top of the character box. A negative ascender height signifies that - * all of the graphic character is below the character baseline. For - * a character rotation other than 0, ascender height loses its - * meaning when the character is lying on its side or is upside down - * with respect to normal viewing orientation. For the general case, - * Ascender Height is the character�s most positive y-axis value. - * For bounded character boxes, for a given character having an - * ascender, ascender height and baseline offset are equal. - * @return the ascender value in millipoints - */ - public int getAscender() { - return charSet.getAscender(size); - } - - /** - * Cap height is the average height of the uppercase characters in - * a font. This value is specified by the designer of a font and is - * usually the height of the uppercase M. - * @return the cap height value in millipoints - */ - public int getCapHeight() { - return charSet.getCapHeight(size); - } - - /** - * Descender depth is the distance from the character baseline to - * the bottom of a character box. A negative descender depth signifies - * that all of the graphic character is above the character baseline. - * @return the descender value in millipoints - */ - public int getDescender() { - return charSet.getDescender(size); - } - - /** - * The first character in the character set - * @return the first character - */ - public int getFirstChar() { - return 0; - } - - /** - * The last character in the character set - * @return the last character - */ - public int getLastChar() { - return 0; - } - - /** - * Get the width (in 1/1000ths of a point size) of all characters - * @return the widths of all characters - */ - public int[] getWidths() { - return charSet.getWidths(); - } - - /** - * XHeight refers to the height of the lower case letters above the baseline. - * @return the typical height of characters - */ - public int getXHeight() { - return charSet.getXHeight(size); - } - - /** - * Get the width (in 1/1000ths of a point size) of the character - * identified by the parameter passed. - * @param character the character from which the width will be calculated - * @return the width of the character - */ - public int getWidth(int character) { - return charSet.getWidth(character, size); - } - - /** - * Map a Unicode character to a code point in the font. - * @param c character to map - * @return the mapped character - */ - public char mapChar(char c) { - return charSet.mapChar(c); - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java deleted file mode 100644 index 71c5dfb6f..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/OutlineFont.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -/** - * A font defined as a set of lines and curves as opposed to a bitmap font. An - * outline font can be scaled to any size and otherwise transformed more easily - * than a bitmap font, and with more attractive results. <p/> - * - */ -public class OutlineFont extends AFPFont { - - /** The character set for this font */ - private CharacterSet charSet = null; - - /** - * Constructor for an outline font. - * - * @param name - * the name of the font - * @param charSet - * the chracter set - */ - public OutlineFont(String name, CharacterSet charSet) { - super(name); - this.charSet = charSet; - } - - /** - * Get the character set metrics. - * - * @return the character set - */ - public CharacterSet getCharacterSet() { - - return charSet; - - } - - /** - * Get the character set metrics. - * @param size ignored - * @return the character set - */ - public CharacterSet getCharacterSet(int size) { - - return charSet; - - } - - /** - * Get the first character in this font. - * @return the first character in this font - */ - public int getFirstChar() { - return charSet.getFirstChar(); - } - - /** - * Get the last character in this font. - * @return the last character in this font - */ - public int getLastChar() { - return charSet.getLastChar(); - } - - /** - * The ascender is the part of a lowercase letter that extends above the - * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also - * used to denote the part of the letter extending above the x-height. - * - * @param size - * the point size - * @return the ascender for the given size - */ - public int getAscender(int size) { - return charSet.getAscender() / 1000 * size; - } - - /** - * Obtains the height of capital letters for the specified point size. - * - * @param size - * the point size - * @return the cap height for the given size - */ - public int getCapHeight(int size) { - return charSet.getCapHeight() / 1000 * size; - } - - /** - * The descender is the part of a lowercase letter that extends below the - * base line, such as "g", "j", or "p". Also used to denote the part of the - * letter extending below the base line. - * - * @param size - * the point size - * @return the descender for the given size - */ - public int getDescender(int size) { - return charSet.getDescender() / 1000 * size; - } - - /** - * The "x-height" (the height of the letter "x"). - * - * @param size - * the point size - * @return the x height for the given size - */ - public int getXHeight(int size) { - return charSet.getXHeight() / 1000 * size; - } - - /** - * Obtain the width of the character for the specified point size. - * @param character the character - * @param size point size - * @return the width of the character for the specified point size - */ - public int getWidth(int character, int size) { - return charSet.getWidth(character) / 1000 * size; - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @param size - * the point size - * @return the widths of all characters - */ - public int[] getWidths(int size) { - int[] widths = charSet.getWidths(); - for (int i = 0; i < widths.length; i++) { - widths[i] = widths[i] / 1000 * size; - } - return widths; - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @return the widths of all characters - */ - public int[] getWidths() { - return getWidths(1000); - } - - /** - * Map a Unicode character to a code point in the font. - * @param c character to map - * @return the mapped character - */ - public char mapChar(char c) { - return charSet.mapChar(c); - } - - /** {@inheritDoc} */ - public String getEncodingName() { - return charSet.getEncoding(); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/fonts/RasterFont.java b/src/java/org/apache/fop/render/afp/fonts/RasterFont.java deleted file mode 100644 index 5c1696aa4..000000000 --- a/src/java/org/apache/fop/render/afp/fonts/RasterFont.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.fonts; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.fo.properties.FixedLength; -import org.apache.fop.render.afp.exceptions.FontRuntimeException; - -/** - * A font where each character is stored as an array of pixels (a bitmap). Such - * fonts are not easily scalable, in contrast to vectored fonts. With this type - * of font, the font metrics information is held in character set files (one for - * each size and style). <p/> - * - */ -public class RasterFont extends AFPFont { - - /** Static logging instance */ - protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts"); - - private Map charSets = new HashMap(); - - private CharacterSet charSet = null; - - /** - * Constructor for the raster font requires the name, weight and style - * attribute to be available as this forms the key to the font. - * - * @param name - * the name of the font - */ - public RasterFont(String name) { - super(name); - } - - /** - * Adds the character set for the given point size - * @param size point size - * @param characterSet character set - */ - public void addCharacterSet(int size, CharacterSet characterSet) { - this.charSets.put(String.valueOf(size), characterSet); - this.charSet = characterSet; - } - - /** - * Get the character set metrics for the specified point size. - * - * @param size the point size - * @return the character set metrics - */ - public CharacterSet getCharacterSet(int size) { - - String pointsize = String.valueOf(size / 1000); - CharacterSet csm = (CharacterSet) charSets.get(pointsize); - if (csm == null) { - csm = (CharacterSet) charSets.get(size + FixedLength.MPT); - } - if (csm == null) { - // Get char set with nearest font size - int distance = Integer.MAX_VALUE; - for (Iterator it = charSets.entrySet().iterator(); it.hasNext();) { - Map.Entry me = (Map.Entry)it.next(); - String key = (String)me.getKey(); - if (!key.endsWith(FixedLength.MPT)) { - int mpt = Integer.parseInt(key) * 1000; - if (Math.abs(size - mpt) < distance) { - distance = Math.abs(size - mpt); - pointsize = (String)me.getKey(); - csm = (CharacterSet)me.getValue(); - } - } - } - if (csm != null) { - charSets.put(size + FixedLength.MPT, csm); - String msg = "No " + (size / 1000) + "pt font " + getFontName() - + " found, substituted with " + pointsize + "pt font"; - log.warn(msg); - } - } - if (csm == null) { - String msg = "No font found for font " + getFontName() - + " with point size " + pointsize; - log.error(msg); - throw new FontRuntimeException(msg); - } - return csm; - - } - - /** - * Get the first character in this font. - * @return the first character in this font. - */ - public int getFirstChar() { - Iterator it = charSets.values().iterator(); - if (it.hasNext()) { - CharacterSet csm = (CharacterSet) it.next(); - return csm.getFirstChar(); - } else { - String msg = "getFirstChar() - No character set found for font:" + getFontName(); - log.error(msg); - throw new FontRuntimeException(msg); - } - } - - /** - * Get the last character in this font. - * @return the last character in this font. - */ - public int getLastChar() { - - Iterator it = charSets.values().iterator(); - if (it.hasNext()) { - CharacterSet csm = (CharacterSet) it.next(); - return csm.getLastChar(); - } else { - String msg = "getLastChar() - No character set found for font:" + getFontName(); - log.error(msg); - throw new FontRuntimeException(msg); - } - - } - - /** - * The ascender is the part of a lowercase letter that extends above the - * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also - * used to denote the part of the letter extending above the x-height. - * - * @param size the point size - * @return the ascender for the given point size - */ - public int getAscender(int size) { - return getCharacterSet(size).getAscender(); - } - - /** - * Obtains the height of capital letters for the specified point size. - * - * @param size the point size - * @return the cap height for the specified point size - */ - public int getCapHeight(int size) { - return getCharacterSet(size).getCapHeight(); - } - - /** - * The descender is the part of a lowercase letter that extends below the - * base line, such as "g", "j", or "p". Also used to denote the part of the - * letter extending below the base line. - * - * @param size the point size - * @return the descender for the specified point size - */ - public int getDescender(int size) { - return getCharacterSet(size).getDescender(); - } - - /** - * The "x-height" (the height of the letter "x"). - * - * @param size the point size - * @return the x height for the given point size - */ - public int getXHeight(int size) { - return getCharacterSet(size).getXHeight(); - } - - /** - * Obtain the width of the character for the specified point size. - * @param character the character - * @param size the point size - * @return the width for the given point size - */ - public int getWidth(int character, int size) { - return getCharacterSet(size).getWidth(character); - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @param size - * the point size - * @return the widths of all characters - */ - public int[] getWidths(int size) { - return getCharacterSet(size).getWidths(); - } - - /** - * Get the getWidth (in 1/1000ths of a point size) of all characters in this - * character set. - * - * @return the widths of all characters - */ - public int[] getWidths() { - return getWidths(1000); - } - - /** - * Map a Unicode character to a code point in the font. - * @param c character to map - * @return the mapped character - */ - public char mapChar(char c) { - return charSet.mapChar(c); - } - - /** {@inheritDoc} */ - public String getEncodingName() { - return charSet.getEncoding(); - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/AFPConstants.java b/src/java/org/apache/fop/render/afp/modca/AFPConstants.java deleted file mode 100644 index 73c39f2f0..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AFPConstants.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -/** - * Constants used by the AFP renderer. - * - */ -public interface AFPConstants { - - /** - * The encoding to use to convert to EBCIDIC - */ - String EBCIDIC_ENCODING = "Cp1146"; - - /** - * The encoding to use to convert to ASCII - */ - String ASCII_ENCODING = "Cp1252"; -} diff --git a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java b/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java deleted file mode 100644 index 0c60ec1d7..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java +++ /dev/null @@ -1,701 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.awt.Color; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.tools.StringUtils; - -/** - * A data stream is a continuous ordered stream of data elements and objects - * conforming to a given format. Application programs can generate data streams - * destined for a presentation service, archive library, presentation device or - * another application program. The strategic presentation data stream - * architectures used is Mixed Object Document Content Architecture (MO:DCA�). - * - * The MO:DCA architecture defines the data stream used by applications to - * describe documents and object envelopes for interchange with other - * applications and application services. Documents defined in the MO:DCA format - * may be archived in a database, then later retrieved, viewed, annotated and - * printed in local or distributed systems environments. Presentation fidelity - * is accommodated by including resource objects in the documents that reference - * them. - * - */ -public class AFPDataStream { - - /** - * Static logging instance - */ - protected static Log log = LogFactory.getLog("org.apache.fop.render.afp.modca"); - - /** - * Boolean completion indicator - */ - private boolean complete = false; - - /** - * The application producing the AFP document - */ -// not used -// private String producer = null; - - /** - * The AFP document object - */ - private Document document = null; - - /** - * The current page group object - */ - private PageGroup currentPageGroup = null; - - /** - * The current page object - */ - private PageObject currentPageObject = null; - - /** - * The current overlay object - */ - private Overlay currentOverlay = null; - - /** - * The current page - */ - private AbstractPageObject currentPage = null; - - /** - * The page count - */ - private int pageCount = 0; - - /** - * The page group count - */ -// not used -// private int pageGroupCount = 0; - - /** - * The overlay count - */ - private int ovlCount = 0; - - /** - * The portrait rotation - */ - private int portraitRotation = 0; - - /** - * The landscape rotation - */ - private int landscapeRotation = 270; - - /** - * The x offset - */ - private int xOffset = 0; - - /** - * The y offset - */ - private int yOffset = 0; - - /** - * The rotation - */ - private int rotation; - - /** - * The outputstream for the data stream - */ - private OutputStream outputStream = null; - - /** - * Default constructor for the AFPDataStream. - */ - public AFPDataStream() { - } - - /** - * The document is started by invoking this method which creates an instance - * of the AFP Document object. - * - * @param docOutputStream - * the outputStream which the document is written to. - */ - public void startDocument(OutputStream docOutputStream) { - - if (document != null) { - String msg = "Invalid state - document already started."; - log.warn("startDocument():: " + msg); - throw new IllegalStateException(msg); - } - - this.document = new Document(); - this.outputStream = docOutputStream; - - } - - /** - * The document is ended by invoking this method which creates an instance - * of the AFP Document object and registers the start with a validation map - * which ensures that methods are not invoked out of the correct sequence. - * - * @throws java.io.IOException - * throws an I/O exception of some sort has occurred - */ - public void endDocument() throws IOException { - - if (complete) { - String msg = "Invalid state - document already ended."; - log.warn("endDocument():: " + msg); - throw new IllegalStateException(msg); - } - - if (currentPageObject != null) { - // End the current page if necessary - endPage(); - } - - if (currentPageGroup != null) { - // End the current page group if necessary - endPageGroup(); - } - - document.endDocument(); - document.writeDataStream(this.outputStream); - this.outputStream.flush(); - - complete = true; - - document = null; - - this.outputStream = null; - } - - /** - * Start a new page. When processing has finished on the current page, the - * {@link #endPage()}method must be invoked to mark the page ending. - * - * @param pageWidth - * the width of the page - * @param pageHeight - * the height of the page - * @param pageRotation - * the rotation of the page - * @param pageWidthResolution - * the width resolution of the page - * @param pageHeightResolution - * the height resolution of the page - */ - public void startPage(int pageWidth, int pageHeight, int pageRotation, - int pageWidthResolution, int pageHeightResolution) { - - String pageName = "PGN" - + StringUtils.lpad(String.valueOf(pageCount++), '0', 5); - - currentPageObject = new PageObject(pageName, pageWidth, pageHeight, - pageRotation, pageWidthResolution, pageHeightResolution); - currentPage = currentPageObject; - currentOverlay = null; - setOffsets(0, 0, 0); - } - - /** - * Start a new overlay. When processing has finished on the current overlay, - * the {@link #endOverlay()}method must be invoked to mark the overlay - * ending. - * - * @param overlayX - * the x position of the overlay on the page - * @param overlayY - * the y position of the overlay on the page - * @param overlayWidth - * the width of the overlay - * @param overlayHeight - * the height of the overlay - * @param overlayWidthResolution - * the width resolution of the overlay - * @param overlayHeightResolution - * the height resolution of the overlay - * @param overlayRotation - * the rotation of the overlay - */ - public void startOverlay(int overlayX, int overlayY, int overlayWidth, - int overlayHeight, int overlayWidthResolution, - int overlayHeightResolution, int overlayRotation) { - - String overlayName = "OVL" - + StringUtils.lpad(String.valueOf(ovlCount++), '0', 5); - - currentOverlay = new Overlay(overlayName, overlayWidth, overlayHeight, - overlayWidthResolution, overlayHeightResolution, - overlayRotation); - currentPageObject.addOverlay(currentOverlay); - currentPageObject.createIncludePageOverlay(overlayName, overlayX, - overlayY, 0); - currentPage = currentOverlay; - setOffsets(0, 0, 0); - } - - /** - * Helper method to mark the end of the current overlay. - */ - public void endOverlay() { - - currentOverlay.endPage(); - currentOverlay = null; - currentPage = currentPageObject; - - } - - /** - * Helper method to save the current page. - * - * @return current page object that was saved - */ - public PageObject savePage() { - - PageObject pageObject = currentPageObject; - if (currentPageGroup != null) { - currentPageGroup.addPage(currentPageObject); - } else { - document.addPage(currentPageObject); - } - currentPageObject = null; - currentPage = null; - return pageObject; - - } - - /** - * Helper method to restore the current page. - * - * @param pageObject - * page object - */ - public void restorePage(PageObject pageObject) { - - currentPageObject = pageObject; - currentPage = pageObject; - - } - - /** - * Helper method to mark the end of the current page. - * - * @throws java.io.IOException - * thrown when an I/O exception of some sort has occurred - */ - public void endPage() throws IOException { - - currentPageObject.endPage(); - if (currentPageGroup != null) { - currentPageGroup.addPage(currentPageObject); - } else { - document.addPage(currentPageObject); - document.writeDataStream(this.outputStream); - } - - currentPageObject = null; - currentPage = null; - - } - - /** - * Sets the offsets to be used for element positioning - * - * @param xOff - * the offset in the x direction - * @param yOff - * the offset in the y direction - * @param rot - * the rotation - */ - public void setOffsets(int xOff, int yOff, int rot) { - this.xOffset = xOff; - this.yOffset = yOff; - this.rotation = rot; - } - - /** - * Helper method to create a map coded font object on the current page, this - * method delegates the construction of the map coded font object to the - * active environment group on the current page. - * - * @param fontReference - * the font number used as the resource identifier - * @param font - * the font - * @param size - * the point size of the font - */ - public void createFont(byte fontReference, AFPFont font, int size) { - - currentPage.createFont(fontReference, font, size); - - } - - /** - * Helper method to create text on the current page, this method delegates - * to the current presentation text object in order to construct the text. - * - * @param fontNumber - * the font number used as the resource identifier - * @param x - * the x coordinate of the text - * @param y - * the y coordinate of the text - * @param col - * the text color - * @param vsci - * The variable space character increment. - * @param ica - * The inter character adjustment. - * @param data - * the text data to create - */ - public void createText(int fontNumber, int x, int y, Color col, int vsci, - int ica, byte[] data) { - - currentPage.createText(fontNumber, x + xOffset, y + yOffset, rotation, - col, vsci, ica, data); - - } - - /** - * Returns an ImageObject used to create an image in the datastream. - * - * @param x - * the x position of the image - * @param y - * the y position of the image - * @param w - * the width of the image - * @param h - * the height of the image - * @param wr - * the width resolution of the image - * @param hr - * the height resolution of the image - * @return ImageObject used to create an image in the datastream - */ - public ImageObject getImageObject(int x, int y, int w, int h, int wr, int hr) { - - int xOrigin; - int yOrigin; - int width; - int height; - int widthResolution; - int heightResolution; - - switch (rotation) { - case 90: - xOrigin = currentPage.getWidth() - y - yOffset; - yOrigin = x + xOffset; - width = h; - height = w; - widthResolution = hr; - heightResolution = wr; - break; - case 180: - xOrigin = currentPage.getWidth() - x - xOffset; - yOrigin = currentPage.getHeight() - y - yOffset; - width = w; - height = h; - widthResolution = wr; - heightResolution = hr; - break; - case 270: - xOrigin = y + yOffset; - yOrigin = currentPage.getHeight() - x - xOffset; - width = h; - height = w; - widthResolution = hr; - heightResolution = wr; - break; - default: - xOrigin = x + xOffset; - yOrigin = y + yOffset; - width = w; - height = h; - widthResolution = wr; - heightResolution = hr; - break; - } - ImageObject io = currentPage.getImageObject(); - io.setImageViewport(xOrigin, yOrigin, width, height, rotation, - widthResolution, heightResolution); - return io; - - } - - /** - * Method to create a line on the current page. - * - * @param x1 - * the first x coordinate of the line - * @param y1 - * the first y coordinate of the line - * @param x2 - * the second x coordinate of the line - * @param y2 - * the second y coordinate of the line - * @param thickness - * the thickness of the line - * @param col - * The text color. - */ - public void createLine(int x1, int y1, int x2, int y2, int thickness, - Color col) { - - currentPage.createLine(x1 + xOffset, y1 + yOffset, x2 + xOffset, y2 - + yOffset, thickness, rotation, col); - - } - - /** - * This method will create shading on the page using the specified - * coordinates (the shading contrast is controlled via the red, green, blue - * parameters, by converting this to grey scale). - * - * @param x - * the x coordinate of the shading - * @param y - * the y coordinate of the shading - * @param w - * the width of the shaded area - * @param h - * the height of the shaded area - * @param red - * the red value - * @param green - * the green value - * @param blue - * the blue value - */ - public void createShading(int x, int y, int w, int h, int red, int green, - int blue) { - - currentPage.createShading(x + xOffset, y + xOffset, w, h, red, green, - blue); - - } - - /** - * Helper method which allows creation of the MPO object, via the AEG. And - * the IPO via the Page. (See actual object for descriptions.) - * - * @param name - * the name of the static overlay - */ - public void createIncludePageOverlay(String name) { - - currentPageObject.createIncludePageOverlay(name, 0, 0, rotation); - ActiveEnvironmentGroup aeg = currentPageObject - .getActiveEnvironmentGroup(); - aeg.createOverlay(name); - - } - - /** - * Helper method which allows creation of the IMM object. - * - * @param name - * the name of the medium map - */ - public void createInvokeMediumMap(String name) { - - if (currentPageGroup == null) { - startPageGroup(); - } - currentPageGroup.createInvokeMediumMap(name); - - } - - /** - * Creates an IncludePageSegment on the current page. - * - * @param name - * the name of the include page segment - * @param x - * the x coordinate for the overlay - * @param y - * the y coordinate for the overlay - */ - public void createIncludePageSegment(String name, int x, int y) { - - int xOrigin; - int yOrigin; - switch (rotation) { - case 90: - xOrigin = currentPage.getWidth() - y - yOffset; - yOrigin = x + xOffset; - break; - case 180: - xOrigin = currentPage.getWidth() - x - xOffset; - yOrigin = currentPage.getHeight() - y - yOffset; - break; - case 270: - xOrigin = y + yOffset; - yOrigin = currentPage.getHeight() - x - xOffset; - break; - default: - xOrigin = x + xOffset; - yOrigin = y + yOffset; - break; - } - currentPage.createIncludePageSegment(name, xOrigin, yOrigin); - - } - - /** - * Creates a TagLogicalElement on the current page. - * - * @param attributes - * the array of key value pairs. - */ - public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) { - - for (int i = 0; i < attributes.length; i++) { - String name = (String) attributes[i].getKey(); - String value = (String) attributes[i].getValue(); - currentPage.createTagLogicalElement(name, value); - } - - } - - /** - * Creates a TagLogicalElement on the current page group. - * - * @param attributes - * the array of key value pairs. - */ - public void createPageGroupTagLogicalElement( - TagLogicalElementBean[] attributes) { - - for (int i = 0; i < attributes.length; i++) { - String name = (String) attributes[i].getKey(); - String value = (String) attributes[i].getValue(); - currentPageGroup.createTagLogicalElement(name, value); - } - - } - - /** - * Creates a TagLogicalElement on the current page or page group - * - * @param name - * The tag name - * @param value - * The tag value - */ - public void createTagLogicalElement(String name, String value) { - - if (currentPageGroup != null) { - currentPageGroup.createTagLogicalElement(name, value); - } else { - currentPage.createTagLogicalElement(name, value); - } - - } - - /** - * Creates a NoOperation item - * - * @param content - * byte data - */ - public void createNoOperation(String content) { - currentPage.createNoOperation(content); - } - - /** - * Start a new page group. When processing has finished on the current page - * group the {@link #endPageGroup()}method must be invoked to mark the page - * group ending. - */ - public void startPageGroup() { - - String pageGroupName = "PGP" - + StringUtils.lpad(String.valueOf(pageCount++), '0', 5); - - currentPageGroup = new PageGroup(pageGroupName); - - } - - /** - * Helper method to mark the end of the page group. - * @throws IOException thrown if an I/O exception of some sort has occurred - */ - public void endPageGroup() throws IOException { - - currentPageGroup.endPageGroup(); - document.addPageGroup(currentPageGroup); - document.writeDataStream(outputStream); - currentPageGroup = null; - - } - - /** - * Sets the rotation to be used for portrait pages, valid values are 0 - * (default), 90, 180, 270. - * - * @param pageRotation - * The rotation in degrees. - */ - public void setPortraitRotation(int pageRotation) { - - if (pageRotation == 0 || pageRotation == 90 || pageRotation == 180 - || pageRotation == 270) { - this.portraitRotation = pageRotation; - } else { - throw new IllegalArgumentException( - "The portrait rotation must be one of the values 0, 90, 180, 270"); - } - - } - - /** - * Sets the rotation to be used for landscape pages, valid values are 0, 90, - * 180, 270 (default). - * - * @param pageRotation - * The rotation in degrees. - */ - public void setLandscapeRotation(int pageRotation) { - - if (pageRotation == 0 || pageRotation == 90 || pageRotation == 180 - || pageRotation == 270) { - this.landscapeRotation = pageRotation; - } else { - throw new IllegalArgumentException( - "The landscape rotation must be one of the values 0, 90, 180, 270"); - } - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java deleted file mode 100644 index ef1b988c0..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This is the base class for all data stream objects. Page objects are - * responsible for building and generating the binary datastream in an - * AFP format. - * - */ -public abstract class AbstractAFPObject { - - /** - * Static logging instance - */ - protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca"); - - /** - * DataStream objects must implement the writeDataStream() - * method to write its data to the given OutputStream - * @param os The outputsteam stream - * @throws java.io.IOException - */ - public abstract void writeDataStream(OutputStream os) throws IOException; - - /** - * Help method to write a set of AFPObjects to the AFP datastream. - * @param afpObjects a list of AFPObjects - * @param os The stream to write to - * @throws java.io.IOException - */ - protected void writeObjectList(List afpObjects, OutputStream os) - throws IOException { - - for (Iterator it = afpObjects.iterator(); it.hasNext(); ) { - ((AbstractAFPObject)it.next()).writeDataStream(os); - } - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java b/src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java deleted file mode 100644 index 83ed9b99a..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -/** - * Base class for AFP descriptor objects - */ -public abstract class AbstractDescriptor extends AbstractAFPObject { - /** width of this descriptor */ - protected int width = 0; - /** height of this descriptor */ - protected int height = 0; - /** width resolution of this descriptor */ - protected int widthResolution = 0; - /** height resolution of this descriptor */ - protected int heightResolution = 0; - - /** - * Constructor a PresentationTextDescriptor for the specified - * width and height. - * @param width The width of the page. - * @param height The height of the page. - * @param widthResolution The width resolution of the page. - * @param heightResolution The height resolution of the page. - */ - public AbstractDescriptor(int width, int height, int widthResolution, int heightResolution) { - this.width = width; - this.height = height; - this.widthResolution = widthResolution; - this.heightResolution = heightResolution; - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java deleted file mode 100644 index 85552a9e9..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.UnsupportedEncodingException; - -/** - * This is the base class for all named data stream objects. - * A named data stream object has an 8 byte EBCIDIC name. - */ -public abstract class AbstractNamedAFPObject extends AbstractAFPObject { - - /** - * The actual name of the object - */ - protected String name = null; - - /** - * The name of the object in EBCIDIC bytes - */ - protected byte[] nameBytes; - - /** - * Constructor for the ActiveEnvironmentGroup, this takes a - * name parameter which should be 8 characters long. - * @param name the object name - */ - public AbstractNamedAFPObject(String name) { - - this.name = name; - if (name.length() < 8) { - name = (name + " ").substring(0, 8); - } else if (name.length() > 8) { - log.warn("Constructor:: name truncated to 8 chars" + name); - name = name.substring(0, 8); - } - - try { - - nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - - } catch (UnsupportedEncodingException usee) { - - nameBytes = name.getBytes(); - log.warn( - "Constructor:: UnsupportedEncodingException translating the name " - + name); - - } - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java deleted file mode 100644 index a99b28107..000000000 --- a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.List; - -import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.tools.StringUtils; - -/** - * Pages contain the data objects that comprise a presentation document. Each - * page has a set of data objects associated with it. Each page within a - * document is independent from any other page, and each must establish its own - * environment parameters. - * - * The page is the level in the document component hierarchy that is used for - * printing or displaying a document's content. The data objects contained in - * the page envelope in the data stream are presented when the page is - * presented. Each data object has layout information associated with it that - * directs the placement and orientation of the data on the page. In addition, - * each page contains layout information that specifies the measurement units, - * page width, and page depth. - * - * A page is initiated by a begin page structured field and terminated by an end - * page structured field. Structured fields that define objects and active - * environment groups or that specify attributes of the page may be encountered - * in page state. - * - */ -public abstract class AbstractPageObject extends AbstractNamedAFPObject { - - /** - * The active environment group for the page - */ - protected ActiveEnvironmentGroup activeEnvironmentGroup = null; - - /** - * The presentation text object, we only have one per page - */ - private PresentationTextObject presentationTextObject = null; - - /** - * The list of objects within the page - */ - protected List objects = new ArrayList(); - - /** - * The list of tag logical elements - */ - protected ArrayList tagLogicalElements = new ArrayList(); - - /** - * The list of the include page segments - */ - protected ArrayList segments = new ArrayList(); - - /** - * The page width - */ - private int width; - - /** - * The page height - */ - private int height; - - /** - * The page rotation - */ - private int rotation = 0; - - /** - * The page state - */ - private boolean complete = false; - - /** - * Construct a new page object for the specified name argument, the page - * name should be an 8 character identifier. - * - * @param name - * the name of the page. - * @param width - * the width of the page. - * @param height - * the height of the page. - * @param rotation - * the rotation of the page. - * @param widthResolution - * the width resolution of the page. - * @param heightResolution - * the height resolution of the page. - */ - public AbstractPageObject(String name, int width, int height, int rotation, - int widthResolution, int heightResolution) { - - super(name); - this.width = width; - this.height = height; - this.rotation = rotation; - - /** - * Every page object must have an ActiveEnvironmentGroup - */ - activeEnvironmentGroup = new ActiveEnvironmentGroup(width, height, - widthResolution, heightResolution); - - if (rotation != 0) { - switch (rotation) { - case 90: - activeEnvironmentGroup.setPosition(width, 0, rotation); - break; - case 180: - activeEnvironmentGroup.setPosition(width, height, rotation); - break; - case 270: - activeEnvironmentGroup.setPosition(0, height, rotation); - break; - default: - } - } - - /** - * We have a presentation text object per page - */ - presentationTextObject = new PresentationTextObject(); - objects.add(presentationTextObject); - - } - - /** - * Helper method to create a map coded font object on the current page, this - * method delegates the construction of the map coded font object to the - * active environment group on the page. - * - * @param fontReference - * the font number used as the resource identifier - * @param font - * the font - * @param size - * the point size of the font - */ - public void createFont(byte fontReference, AFPFont font, int size) { - - activeEnvironmentGroup.createFont(fontReference, font, size, 0); - - } - - /** - * Helper method to create a line on the current page, this method delegates - * to the presentation text object in order to construct the line. - * - * @param x1 - * the first x coordinate of the line - * @param y1 - * the first y coordinate of the line - * @param x2 - * the second x coordinate of the line - * @param y2 - * the second y coordinate of the line - * @param thickness - * the thickness of the line - * @param lineRotation - * the rotation of the line - * @param col - * The text color. - */ - public void createLine(int x1, int y1, int x2, int y2, int thickness, - int lineRotation, Color col) { - - if (presentationTextObject == null) { - presentationTextObject = new PresentationTextObject(); - objects.add(presentationTextObject); - } - presentationTextObject.createLineData(x1, y1, x2, y2, thickness, lineRotation, col); - - } - - /** - * Helper method to create text on the current page, this method delegates - * to the presentation text object in order to construct the text. - * - * @param fontNumber - * the font number used as the resource identifier - * @param x - * the x coordinate of the text data - * @param y - * the y coordinate of the text data - * @param textRotation - * the rotation of the text data - * @param col - * the text color - * @param vsci - * The variable space character increment. - * @param ica - * The inter character adjustment. - * @param data - * the text data to create - */ - public void createText(int fontNumber, int x, int y, int textRotation, Color col, - int vsci, int ica, byte[] data) { - - if (presentationTextObject == null) { - presentationTextObject = new PresentationTextObject(); - objects.add(presentationTextObject); - } - presentationTextObject.createTextData(fontNumber, x, y, textRotation, col, vsci, ica, data); - - } - - /** - * Helper method to mark the end of the page. This should end the control - * sequence on the current presenation text object. - */ - public void endPage() { - - if (presentationTextObject != null) { - presentationTextObject.endControlSequence(); - } - - complete = true; - - } - - /** - * This method will create shading on the page using the specified - * coordinates (the shading contrast is controlled via the red, green blue - * parameters, by converting this to grey scale). - * - * @param x - * the x coordinate of the shading - * @param y - * the y coordinate of the shading - * @param w - * the width of the shaded area - * @param h - * the height of the shaded area - * @param red - * the red value - * @param green - * the green value - * @param blue - * the blue value - */ - public void createShading(int x, int y, int w, int h, int red, int green, - int blue) { - - int xCoord = 0; - int yCoord = 0; - int areaWidth = 0; - int areaHeight = 0; - - switch (rotation) { - case 90: - xCoord = areaWidth - y - h; - yCoord = x; - areaWidth = h; - areaHeight = w; - break; - case 180: - xCoord = areaWidth - x - w; - yCoord = areaHeight - y - h; - areaWidth = w; - areaHeight = h; - break; - case 270: - xCoord = y; - yCoord = areaHeight - x - w; - areaWidth = h; - areaHeight = w; - break; - default: - xCoord = x; - yCoord = y; - areaWidth = w; - areaHeight = h; - break; - } - - // Convert the color to grey scale - float shade = (float) ((red * 0.3) + (green * 0.59) + (blue * 0.11)); - - int greyscale = Math.round((shade / 255) * 16); - - String imageName = "IMG" - + StringUtils.lpad(String.valueOf(objects.size() + 1), - '0', 5); - - IMImageObject io = new IMImageObject(imageName); - ImageOutputControl ioc = new ImageOutputControl(0, 0); - ImageInputDescriptor iid = new ImageInputDescriptor(); - ImageCellPosition icp = new ImageCellPosition(xCoord, yCoord); - icp.setXFillSize(areaWidth); - icp.setYFillSize(areaHeight); - icp.setXSize(64); - icp.setYSize(8); - - //defining this as a resource - ImageRasterData ird = new ImageRasterData(ImageRasterPattern - .getRasterData(greyscale)); - - io.setImageOutputControl(ioc); - io.setImageInputDescriptor(iid); - io.setImageCellPosition(icp); - io.setImageRasterData(ird); - objects.add(io); - - } - - /** - * Helper method to create an image on the current page and to return - * the object. - * @return the image object - */ - public ImageObject getImageObject() { - - if (presentationTextObject != null) { - presentationTextObject.endControlSequence(); - } - presentationTextObject = null; - - String imageName = "IMG" - + StringUtils.lpad(String.valueOf(objects.size() + 1), - '0', 5); - - ImageObject io = new ImageObject(imageName); - objects.add(io); - return io; - } - - /** - * Creates a TagLogicalElement on the page. - * - * @param name - * the name of the tag - * @param value - * the value of the tag - */ - public void createTagLogicalElement(String name, String value) { - - TagLogicalElement tle = new TagLogicalElement(name, value); - tagLogicalElements.add(tle); - - } - - /** - * Creates a NoOperation on the page. - * - * @param content the byte data - */ - public void createNoOperation(String content) { - - NoOperation noOp = new NoOperation(content); - objects.add(noOp); - - } - - /** - * Creates an IncludePageSegment on the current page. - * - * @param name - * the name of the page segment - * @param xCoor - * the x cooridinate of the page segment. - * @param yCoor - * the y cooridinate of the page segment. - */ - public void createIncludePageSegment(String name, int xCoor, int yCoor) { - - IncludePageSegment ips = new IncludePageSegment(name, xCoor, yCoor); - segments.add(ips); - - } - - /** - * Returns the ActiveEnvironmentGroup associated with this page. - * - * @return the ActiveEnvironmentGroup object - */ - public ActiveEnvironmentGroup getActiveEnvironmentGroup() { - return activeEnvironmentGroup; - } - - /** - * Returns an indication if the page is complete - * @return whether this page is complete - */ - public boolean isComplete() { - return complete; - } - - /** - * Returns the height of the page - * @return the height of the page - */ - public int getHeight() { - return height; - } - - /** - * Returns the width of the page - * @return the width of the page - */ - public int getWidth() { - return width; - } - - /** - * Returns the rotation of the page - * @return the rotation of the page - */ - public int getRotation() { - return rotation; - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java deleted file mode 100644 index 3e341c735..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -import org.apache.fop.render.afp.fonts.AFPFont; - -/** - * An Active Environment Group (AEG) is associated with each page, - * and is contained in the page's begin-end envelope in the data stream. - * The active environment group contains layout and formatting information - * that defines the measurement units and size of the page, and may contain - * resource information. - * - * Any objects that are required for page presentation and that are to be - * treated as resource objects must be mapped with a map structured field - * in the AEG. The scope of an active environment group is the scope of its - * containing page or overlay. - * - */ -public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject { - - /** - * Default name for the active environment group - */ - private static final String DEFAULT_NAME = "AEG00001"; - - /** - * The collection of MapCodedFont objects - */ - private ArrayList mapCodedFonts = new ArrayList(); - - /** - * The Object Area Descriptor for the active environment group - */ - private ObjectAreaDescriptor objectAreaDescriptor = null; - - /** - * The Object Area Position for the active environment group - */ - private ObjectAreaPosition objectAreaPosition = null; - - /** - * The PresentationTextDescriptor for the active environment group - */ - private PresentationTextDescriptor presentationTextDataDescriptor = null; - - /** - * The PageDescriptor for the active environment group - */ - private PageDescriptor pageDescriptor = null; - - /** - * The collection of MapPageOverlay objects - */ - private ArrayList mapPageOverlays = new ArrayList(); - - /** - * Default constructor for the ActiveEnvironmentGroup. - * @param width the page width - * @param height the page height - * @param widthResolution the page width resolution - * @param heightResolution the page height resolution - */ - public ActiveEnvironmentGroup(int width, int height, - int widthResolution, int heightResolution) { - - this(DEFAULT_NAME, width, height, widthResolution, heightResolution); - - } - - /** - * Constructor for the ActiveEnvironmentGroup, this takes a - * name parameter which must be 8 characters long. - * @param name the active environment group name - * @param width the page width - * @param height the page height - * @param widthResolution the page width resolution - * @param heightResolution the page height resolution - */ - public ActiveEnvironmentGroup(String name, int width, int height, - int widthResolution, int heightResolution) { - - super(name); - - // Create PageDescriptor - pageDescriptor = new PageDescriptor(width, height, widthResolution, heightResolution); - - // Create ObjectAreaDescriptor - objectAreaDescriptor = new ObjectAreaDescriptor(width, height, - widthResolution, heightResolution); - - // Create PresentationTextDataDescriptor - presentationTextDataDescriptor = new PresentationTextDescriptor(width, height, - widthResolution, heightResolution); - - } - - /** - * Set the position of the object area - * @param x the x offset - * @param y the y offset - * @param rotation the rotation - */ - public void setPosition(int x, int y, int rotation) { - - // Create ObjectAreaPosition - objectAreaPosition = new ObjectAreaPosition(x, y, rotation); - - } - - /** - * Accessor method to obtain the PageDescriptor object of the - * active environment group. - * @return the page descriptor object - */ - public PageDescriptor getPageDescriptor() { - - return pageDescriptor; - - } - - /** - * Accessor method to obtain the PresentationTextDataDescriptor object of - * the active environment group. - * @return the presentation text descriptor - */ - public PresentationTextDescriptor getPresentationTextDataDescriptor() { - - return presentationTextDataDescriptor; - - } - - /** - * Accessor method to write the AFP datastream for the active environment group. - * @param os The stream to write to - * @throws java.io.IOException throws if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - writeObjectList(mapCodedFonts, os); - - writeObjectList(mapPageOverlays, os); - - pageDescriptor.writeDataStream(os); - - if (objectAreaDescriptor != null && objectAreaPosition != null) { - objectAreaDescriptor.writeDataStream(os); - objectAreaPosition.writeDataStream(os); - } - - presentationTextDataDescriptor.writeDataStream(os); - - writeEnd(os); - - } - - /** - * Helper method to write the start of the active environment group. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xC9; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the active environment group. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xC9; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Method to create a map coded font object - * @param fontReference the font number used as the resource identifier - * @param font the font - * @param size the point size of the font - * @param orientation the orientation of the font (e.g. 0, 90, 180, 270) - */ - public void createFont( - byte fontReference, - AFPFont font, - int size, - int orientation) { - - MapCodedFont mcf = getCurrentMapCodedFont(); - - if (mcf == null) { - mcf = new MapCodedFont(); - mapCodedFonts.add(mcf); - } - - try { - - mcf.addFont( - fontReference, - font, - size, - orientation); - - } catch (MaximumSizeExceededException msee) { - - mcf = new MapCodedFont(); - mapCodedFonts.add(mcf); - - try { - - mcf.addFont( - fontReference, - font, - size, - orientation); - - } catch (MaximumSizeExceededException ex) { - - // Should never happen (but log just in case) - log.error("createFont():: resulted in a MaximumSizeExceededException"); - - } - - } - - } - - /** - * Actually creates the MPO object. - * Also creates the supporting object (an IPO) - * @param name the name of the overlay to be used - */ - public void createOverlay(String name) { - - MapPageOverlay mpo = getCurrentMapPageOverlay(); - - if (mpo == null) { - mpo = new MapPageOverlay(); - mapPageOverlays.add(mpo); - } - - try { - - mpo.addOverlay(name); - - } catch (MaximumSizeExceededException msee) { - mpo = new MapPageOverlay(); - mapPageOverlays.add(mpo); - try { - mpo.addOverlay(name); - } catch (MaximumSizeExceededException ex) { - // Should never happen (but log just in case) - log.error("createOverlay():: resulted in a MaximumSizeExceededException"); - } - } - } - - /** - * Getter method for the most recent MapCodedFont added to the - * Active Environment Group (returns null if no MapCodedFonts exist) - * @return the most recent Map Coded Font. - */ - private MapCodedFont getCurrentMapCodedFont() { - - int size = mapCodedFonts.size(); - if (size > 0) { - return (MapCodedFont) mapCodedFonts.get(mapCodedFonts.size() - 1); - } else { - return null; - } - - } - - /** - * Getter method for the most recent MapPageOverlay added to the - * Active Environment Group (returns null if no MapPageOverlay exist) - * @return the most recent Map Coded Font - */ - private MapPageOverlay getCurrentMapPageOverlay() { - - int size = mapPageOverlays.size(); - if (size > 0) { - return (MapPageOverlay) mapPageOverlays.get( - mapPageOverlays.size() - 1); - } else { - return null; - } - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/Document.java b/src/java/org/apache/fop/render/afp/modca/Document.java deleted file mode 100644 index 3d2d40a3a..000000000 --- a/src/java/org/apache/fop/render/afp/modca/Document.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.List; - -/** - * The document is the highest level of the MO:DCA data-stream document - * component hierarchy. Documents can be made up of pages, and the pages, - * which are at the intermediate level, can be made up of objects. Objects - * are at the lowest level, and can be bar codes, graphics, images, and - * presentation text. - * - * At each level of the hierarchy certain sets of MO:DCA data structures, - * called structured fields, are permissible. The document, pages and objects - * are bounded by structured fields that define their beginnings and their ends. - * These structured fields, called begin-end pairs, provide an envelope for the - * data-stream components. This feature enables a processor of the data stream - * that is not fully compliant with the architecture to bypass those objects - * that are beyond its scope, and to process the data stream to the best of its - * abilities. - * - * A presentation document is one that has been formatted and is intended for - * presentation, usually on a printer or display device. A data stream containing - * a presentation document should produce the same document content in the - * same format on different printers or display devices dependent, however, - * on the capabilities of each of the printers or display devices. A presentation - * document can reference resources that are to be included as part of the - * document to be presented. - * - */ -public final class Document extends AbstractNamedAFPObject { - - /** - * Ststic default name reference - */ - private static final String DEFAULT_NAME = "DOC00001"; - - /** - * A list of the objects in the document - */ - private List objects = new java.util.ArrayList(); - - /** - * The document started state - */ - private boolean started = false; - - /** - * The document completion state - */ - private boolean complete = false; - - /** - * Default constructor for the document object. - */ - public Document() { - this(DEFAULT_NAME); - } - - /** - * Constructor for the document object. - * @param name The name of the document - */ - public Document(String name) { - - super(name); - - } - - /** - * Adds a page to the document. - * @param page - the Page object - */ - public void addPage(PageObject page) { - if (!objects.contains(page)) { - objects.add(page); - } - } - - /** - * Adds a PageGroup to the document. - * @param pageGroup the PageGroup object - */ - public void addPageGroup(PageGroup pageGroup) { - objects.add(pageGroup); - } - - /** - * Method to mark the end of the page group. - */ - public void endDocument() { - - complete = true; - - } - - /** - * Returns an indication if the page group is complete - * @return whether or not this page group is complete - */ - public boolean isComplete() { - return complete; - } - - /** - * Accessor method to write the AFP datastream for document. - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - if (!started) { - writeStart(os); - started = true; - } - - for (Iterator it = objects.iterator(); it.hasNext();) { - AbstractAFPObject ao = (AbstractAFPObject)it.next(); - if (ao instanceof PageObject && ((PageObject)ao).isComplete() - || ao instanceof PageGroup && ((PageGroup)ao).isComplete()) { - ao.writeDataStream(os); - it.remove(); - } else { - break; - } - } - - if (complete) { - writeEnd(os); - } - - } - - /** - * Helper method to write the start of the Document - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xA8; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the Document. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xA8; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/IMImageObject.java b/src/java/org/apache/fop/render/afp/modca/IMImageObject.java deleted file mode 100644 index bb43950dd..000000000 --- a/src/java/org/apache/fop/render/afp/modca/IMImageObject.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An IM image data object specifies the contents of a raster image and - * its placement on a page, overlay, or page segment. An IM image can be - * either simple or complex. A simple image is composed of one or more Image - * Raster Data (IRD) structured fields that define the raster pattern for the - * entire image. A complex image is divided into regions called image cells. - * Each image cell is composed of one or more IRD structured fields that define - * the raster pattern for the image cell, and one Image Cell Position (ICP) - * structured field that defines the position of the image cell relative to - * the origin of the entire image. Each ICP also specifies the size of the - * image cell and a fill rectangle into which the cell is replicated. - * <p/> - */ -public class IMImageObject extends AbstractNamedAFPObject { - - /** - * The image output control - */ - private ImageOutputControl imageOutputControl = null; - - /** - * The image input descriptor - */ - private ImageInputDescriptor imageInputDescriptor = null; - - /** - * The image cell position - */ - private ImageCellPosition imageCellPosition = null; - - /** - * The image rastor data - */ - private ImageRasterData imageRasterData = null; - - /** - * Constructor for the image object with the specified name, - * the name must be a fixed length of eight characters. - * @param name The name of the image. - */ - public IMImageObject(String name) { - - super(name); - - } - - /** - * Sets the ImageOutputControl. - * @param imageOutputControl The imageOutputControl to set - */ - public void setImageOutputControl(ImageOutputControl imageOutputControl) { - this.imageOutputControl = imageOutputControl; - } - - /** - * Sets the ImageCellPosition. - * @param imageCellPosition The imageCellPosition to set - */ - public void setImageCellPosition(ImageCellPosition imageCellPosition) { - this.imageCellPosition = imageCellPosition; - } - - /** - * Sets the ImageInputDescriptor. - * @param imageInputDescriptor The imageInputDescriptor to set - */ - public void setImageInputDescriptor(ImageInputDescriptor imageInputDescriptor) { - this.imageInputDescriptor = imageInputDescriptor; - } - - /** - * Sets the ImageRastorData. - * @param imageRasterData The imageRasterData to set - */ - public void setImageRasterData(ImageRasterData imageRasterData) { - this.imageRasterData = imageRasterData; - } - - /** - * Accessor method to write the AFP datastream for the IM Image Objetc - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - if (imageOutputControl != null) { - imageOutputControl.writeDataStream(os); - } - - if (imageInputDescriptor != null) { - imageInputDescriptor.writeDataStream(os); - } - - if (imageCellPosition != null) { - imageCellPosition.writeDataStream(os); - } - - if (imageRasterData != null) { - imageRasterData.writeDataStream(os); - } - - writeEnd(os); - - } - - /** - * Helper method to write the start of the IM Image Object. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0x7B; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the IM Image Object. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0x7B; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java b/src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java deleted file mode 100644 index c0b28904d..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The IM Image Cell Position structured field specifies the placement, - * size, and replication of IM image cells. - */ -public class ImageCellPosition extends AbstractAFPObject { - - /** - * Offset of image cell in X direction - */ - private int xOffset = 0; - - /** - * Offset of image cell in Y direction - */ - private int yOffset = 0; - - /** - * Size of image cell in X direction - */ - private byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF}; - - /** - * Size of image cell in Y direction - */ - private byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF}; - - /** - * Size of fill rectangle in X direction - */ - private byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; - - /** - * Size of fill rectangle in Y direction - */ - private byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; - - /** - * Constructor for the ImageCellPosition - * @param x The offset of image cell in X direction - * @param y The offset of image cell in Y direction - */ - public ImageCellPosition(int x, int y) { - xOffset = x; - yOffset = y; - } - - /** - * Accessor method to write the AFP datastream for the Image Cell Position - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - byte[] data = new byte[21]; - - data[0] = 0x5A; - - data[1] = 0x00; - data[2] = 0x14; - - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAC; - data[5] = (byte) 0x7B; - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - - /** - * Specifies the offset along the Xp direction, in image points, - * of this image cell from the IM image object area origin. - */ - byte[] x1 = BinaryUtils.convert(xOffset, 2); - data[9] = x1[0]; - data[10] = x1[1]; - - /** - * Specifies the offset along the Yp direction, in image points, - * of this image cell from the IM image object area origin. - */ - byte[] x2 = BinaryUtils.convert(yOffset, 2); - data[11] = x2[0]; - data[12] = x2[1]; - - data[13] = xSize[0]; - data[14] = xSize[1]; - - data[15] = ySize[0]; - data[16] = ySize[1]; - - data[17] = xFillSize[0]; - data[18] = xFillSize[1]; - - data[19] = yFillSize[0]; - data[20] = yFillSize[1]; - - os.write(data); - } - - /** - * Specifies the extent in the X direction, in image points, - * of this image cell. A value of X'FFFF' indicates that the - * default extent specified in bytes 28 and 29 of the Image - * Input Descriptor (IID) is to be used. - * @param xcSize The size to set. - */ - public void setXSize(int xcSize) { - byte[] x = BinaryUtils.convert(xcSize, 2); - xSize[0] = x[0]; - xSize[1] = x[1]; - } - - /** - * Specifies the extent of the fill rectangle in the X direction, - * in image points. This value can be smaller than, equal to, or - * larger than the image cell extent in the X direction (XCSize). - * A value of X'FFFF' indicates that the image cell X-extent should - * be used as the fill rectangle X-extent. The fill rectangle is - * filled in the X direction by repeating the image cell in the - * X direction. The image cell can be truncated to fit the rectangle. - * @param size The size to set. - */ - public void setXFillSize(int size) { - byte[] x = BinaryUtils.convert(size, 2); - this.xFillSize[0] = x[0]; - this.xFillSize[1] = x[1]; - } - - /** - * Specifies the extent in the Y direction, in image points, - * of this image cell. A value of X'FFFF' indicates that the - * default extent specified in bytes 30 and 31 of the Image - * Input Descriptor (IID) is to be used. - * @param size The size to set. - */ - public void setYSize(int size) { - byte[] x = BinaryUtils.convert(size, 2); - this.ySize[0] = x[0]; - this.ySize[1] = x[1]; - } - - /** - * Specifies the extent of the fill rectangle in the Y direction, - * in image points. This value can be smaller than, equal to, or - * larger than the image cell extent in the Y direction (YCSize). - * A value of X'FFFF' indicates that the image cell Y-extent should - * be used as the fill rectangle Y-extent. The fill rectangle is - * filled in the Y direction by repeating the image cell in the - * Y direction. The image cell can be truncated to fit the rectangle. - * @param size The size to set. - */ - public void setYFillSize(int size) { - byte[] x = BinaryUtils.convert(size, 2); - this.yFillSize[0] = x[0]; - this.yFillSize[1] = x[1]; - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ImageContent.java b/src/java/org/apache/fop/render/afp/modca/ImageContent.java deleted file mode 100644 index e6f9f1857..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageContent.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - */ -public class ImageContent extends AbstractAFPObject { - - /** - * The image size parameter - */ - private ImageSizeParameter _imageSizeParameter = null; - - /** - * The image encoding - */ - private byte _encoding = 0x03; - - /** - * The image ide size - */ - private byte _size = 1; - - /** - * The image compression - */ - private byte _compression = (byte)0xC0; - - /** - * The image color model - */ - private byte _colorModel = 0x01; - - /** - * The image data - */ - private byte _data[] = null; - - /** - * Constructor for the image content - */ - public ImageContent() { - - } - - /** - * Sets the image size parameters - * resolution, hsize and vsize. - * @param hresol The horizontal resolution of the image. - * @param vresol The vertical resolution of the image. - * @param hsize The horizontal size of the image. - * @param vsize The vertival size of the image. - */ - public void setImageSize(int hresol, int vresol, int hsize, int vsize) { - _imageSizeParameter = new ImageSizeParameter(hresol, vresol, hsize, vsize); - } - - /** - * Sets the image encoding. - * @param encoding The image encoding. - */ - public void setImageEncoding(byte encoding) { - _encoding = encoding; - } - - /** - * Sets the image compression. - * @param compression The image compression. - */ - public void setImageCompression(byte compression) { - _compression = compression; - } - - /** - * Sets the image IDE size. - * @param size The IDE size. - */ - public void setImageIDESize(byte size) { - _size = size; - } - - /** - * Sets the image IDE color model. - * @param colorModel the IDE color model. - */ - public void setImageIDEColorModel(byte colorModel) { - _colorModel = colorModel; - } - - /** - * Set the data of the image. - */ - public void setImageData(byte data[]) { - _data = data; - } - - /** - * Accessor method to write the AFP datastream for the Image Content - * @param os The stream to write to - * @throws java.io.IOException - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - if (_imageSizeParameter != null) { - _imageSizeParameter.writeDataStream(os); - } - - os.write(getImageEncodingParameter()); - - os.write(getImageIDESizeParameter()); - - os.write(getIDEStructureParameter()); - - os.write(getExternalAlgorithmParameter()); - - if (_data != null) { - int off = 0; - while (off < _data.length) { - int len = Math.min(30000, _data.length - off); - os.write(getImageDataStart(len)); - os.write(_data, off, len); - off += len; - } - } - - writeEnd(os); - - } - - /** - * Helper method to write the start of the Image Content. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - (byte)0x91, // ID - 0x01, // Length - (byte)0xff, // Object Type = IOCA Image Object - }; - - os.write(data); - - } - - /** - * Helper method to write the end of the Image Content. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - (byte)0x93, // ID - 0x00, // Length - }; - - os.write(data); - - } - - /** - * Helper method to return the start of the image segment. - * @return byte[] The data stream. - */ - private byte[] getImageDataStart(int len) { - - byte[] data = new byte[] { - (byte)0xFE, // ID - (byte)0x92, // ID - 0x00, // Length - 0x00, // Length - }; - - byte[] l = BinaryUtils.convert(len, 2); - data[2] = l[0]; - data[3] = l[1]; - - - return data; - - } - - /** - * Helper method to return the image encoding parameter. - * @return byte[] The data stream. - */ - private byte[] getImageEncodingParameter() { - - byte[] data = new byte[] { - (byte)0x95, // ID - 0x02, // Length - _encoding, - 0x01, // RECID - }; - - return data; - - } - - /** - * Helper method to return the external algorithm parameter. - * @return byte[] The data stream. - */ - private byte[] getExternalAlgorithmParameter() { - - if (_encoding == (byte)0x83 && _compression != 0) { - byte[] data = new byte[] { - (byte)0x95, // ID - 0x00, // Length - 0x10, // ALGTYPE = Compression Algorithm - 0x00, // Reserved - (byte)0x83, // COMPRID = JPEG - 0x00, // Reserved - 0x00, // Reserved - 0x00, // Reserved - _compression, // MARKER - 0x00, // Reserved - 0x00, // Reserved - 0x00, // Reserved - }; - data[1] = (byte)(data.length - 2); - return data; - } - return new byte[0]; - } - - /** - * Helper method to return the image encoding parameter. - * @return byte[] The data stream. - */ - private byte[] getImageIDESizeParameter() { - - byte[] data = new byte[] { - (byte)0x96, // ID - 0x01, // Length - _size, - }; - - return data; - - } - - /** - * Helper method to return the external algorithm parameter. - * @return byte[] The data stream. - */ - private byte[] getIDEStructureParameter() { - - if (_colorModel != 0 && _size == 24) { - byte bits = (byte)(_size / 3); - byte[] data = new byte[] { - (byte)0x9B, // ID - 0x00, // Length - 0x00, // FLAGS - 0x00, // Reserved - _colorModel, // COLOR MODEL - 0x00, // Reserved - 0x00, // Reserved - 0x00, // Reserved - bits, - bits, - bits, - }; - data[1] = (byte)(data.length - 2); - return data; - } - return new byte[0]; - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java deleted file mode 100644 index 9250f0c7f..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - */ -public class ImageDataDescriptor extends AbstractAFPObject { - - private int _xresol = 0; - private int _yresol = 0; - private int _width = 0; - private int _height = 0; - - /** - * Constructor for a ImageDataDescriptor for the specified - * resolution, width and height. - * @param xresol The horizontal resolution of the image. - * @param yresol The vertical resolution of the image. - * @param width The width of the image. - * @param height The height of the height. - */ - public ImageDataDescriptor(int xresol, int yresol, int width, int height) { - - _xresol = xresol; - _yresol = yresol; - _width = width; - _height = height; - - } - - /** - * Accessor method to write the AFP datastream for the Image Data Descriptor - * @param os The stream to write to - * @throws java.io.IOException - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - 0x5A, - 0x00, - 0x20, - (byte) 0xD3, - (byte) 0xA6, - (byte) 0xFB, - 0x00, // Flags - 0x00, // Reserved - 0x00, // Reserved - 0x00, // Unit base - 10 Inches - 0x00, // XRESOL - 0x00, // - 0x00, // YRESOL - 0x00, // - 0x00, // XSIZE - 0x00, // - 0x00, // YSIZE - 0x00, // - (byte)0xF7, // ID = Set IOCA Function Set - 0x02, // Length - 0x01, // Category = Function set identifier - 0x0B, // FCNSET = IOCA FS 11 - }; - - byte[] l = BinaryUtils.convert(data.length - 1, 2); - data[1] = l[0]; - data[2] = l[1]; - - byte[] x = BinaryUtils.convert(_xresol, 2); - data[10] = x[0]; - data[11] = x[1]; - - byte[] y = BinaryUtils.convert(_yresol, 2); - data[12] = y[0]; - data[13] = y[1]; - - byte[] w = BinaryUtils.convert(_width, 2); - data[14] = w[0]; - data[15] = w[1]; - - byte[] h = BinaryUtils.convert(_height, 2); - data[16] = h[0]; - data[17] = h[1]; - - os.write(data); - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java deleted file mode 100644 index bba416c88..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The IM Image Input Descriptor structured field contains the - * descriptor data for an IM image data object. This data specifies - * the resolution, size, and color of the IM image. - */ -public class ImageInputDescriptor extends AbstractAFPObject { - - /** - * The resolution of the raster image (default 240) - */ - private int resolution = 240; - - - /** - * Accessor method to write the AFP datastream for the Image Input Descriptor - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - - byte[] data = new byte[45]; - - data[0] = 0x5A; - data[1] = 0x00; - data[2] = 0x2C; - data[3] = (byte) 0xD3; - data[4] = (byte) 0xA6; - data[5] = (byte) 0x7B; - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - - // Constant data. - data[9] = 0x00; - data[10] = 0x00; - data[11] = 0x09; - data[12] = 0x60; - data[13] = 0x09; - data[14] = 0x60; - data[15] = 0x00; - data[16] = 0x00; - data[17] = 0x00; - data[18] = 0x00; - data[19] = 0x00; - data[20] = 0x00; - - // X Base (Fixed x00) - data[21] = 0x00; - // Y Base (Fixed x00) - data[22] = 0x00; - - byte[] imagepoints = BinaryUtils.convert(resolution * 10, 2); - - /** - * Specifies the number of image points per unit base for the X axis - * of the image. This value is ten times the resolution of the image - * in the X direction. - */ - data[23] = imagepoints[0]; - data[24] = imagepoints[1]; - - /** - * Specifies the number of image points per unit base for the Y axis - * of the image. This value is ten times the resolution of the image - * in the Y direction. - */ - data[25] = imagepoints[0]; - data[26] = imagepoints[1]; - - /** - * Specifies the extent in the X direction, in image points, of an - * non-celled (simple) image. - */ - data[27] = 0x00; - data[28] = 0x01; - - /** - * Specifies the extent in the Y direction, in image points, of an - * non-celled (simple) image. - */ - data[29] = 0x00; - data[30] = 0x01; - - // Constant Data - data[31] = 0x00; - data[32] = 0x00; - data[33] = 0x00; - data[34] = 0x00; - data[35] = 0x2D; - data[36] = 0x00; - - // Default size of image cell in X direction - data[37] = 0x00; - data[38] = 0x01; - - // Default size of image cell in Y direction - data[39] = 0x00; - data[40] = 0x01; - - // Constant Data - data[41] = 0x00; - data[42] = 0x01; - - // Image Color - data[43] = (byte)0xFF; - data[44] = (byte)0xFF; - - os.write(data); - - } - - /** - * Sets the resolution information for the raster image - * the default value is a resolution of 240 dpi. - * @param resolution The resolution value - */ - public void setResolution(int resolution) { - this.resolution = resolution; - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ImageObject.java b/src/java/org/apache/fop/render/afp/modca/ImageObject.java deleted file mode 100644 index 66c46c872..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageObject.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * An IOCA Image Data Object - */ -public class ImageObject extends AbstractNamedAFPObject { - - /** - * The object environment group - */ - private ObjectEnvironmentGroup objectEnvironmentGroup = null; - - /** - * The image segment - */ - private ImageSegment imageSegment = null; - - /** - * Constructor for the image object with the specified name, - * the name must be a fixed length of eight characters. - * @param name The name of the image. - */ - public ImageObject(String name) { - - super(name); - - } - - /** - * Sets the image display area position and size. - * - * @param x - * the x position of the image - * @param y - * the y position of the image - * @param w - * the width of the image - * @param h - * the height of the image - * @param r - * the rotation of the image - * @param wr - * the width resolution of the image - * @param hr - * the height resolution of the image - */ - public void setImageViewport(int x, int y, int w, int h, int r, int wr, int hr) { - if (objectEnvironmentGroup == null) { - objectEnvironmentGroup = new ObjectEnvironmentGroup(); - } - objectEnvironmentGroup.setObjectArea(x, y, w, h, r, wr, hr); - } - - /** - * Set the dimensions of the image. - * @param xresol the x resolution of the image - * @param yresol the y resolution of the image - * @param width the image width - * @param height the image height - */ - public void setImageParameters(int xresol, int yresol, int width, int height) { - if (objectEnvironmentGroup == null) { - objectEnvironmentGroup = new ObjectEnvironmentGroup(); - } - objectEnvironmentGroup.setImageData(xresol, yresol, width, height); - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageSize(xresol, yresol, width, height); - } - - /** - * Sets the image encoding. - * @param encoding The image encoding. - */ - public void setImageEncoding(byte encoding) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageEncoding(encoding); - } - - /** - * Sets the image compression. - * @param compression The image compression. - */ - public void setImageCompression(byte compression) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageCompression(compression); - } - - /** - * Sets the image IDE size. - * @param size The IDE size. - */ - public void setImageIDESize(byte size) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageIDESize(size); - } - - /** - * Sets the image IDE color model. - * @param colorModel the IDE color model. - */ - public void setImageIDEColorModel(byte colorModel) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageIDEColorModel(colorModel); - } - - /** - * Set the data of the image. - * @param data The image data - */ - public void setImageData(byte[] data) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageData(data); - } - - /** - * Sets the ObjectEnvironmentGroup. - * @param objectEnvironmentGroup The objectEnvironmentGroup to set - */ - public void setObjectEnvironmentGroup(ObjectEnvironmentGroup objectEnvironmentGroup) { - this.objectEnvironmentGroup = objectEnvironmentGroup; - } - - /** - * Helper method to return the start of the image object. - * @return byte[] The data stream. - */ - private byte[] getIPDStart(int len) { - - byte[] data = new byte[] { - - 0x5A, // Structured field identifier - 0x00, // Length byte 1 - 0x10, // Length byte 2 - (byte) 0xD3, // Structured field id byte 1 - (byte) 0xEE, // Structured field id byte 2 - (byte) 0xFB, // Structured field id byte 3 - 0x00, // Flags - 0x00, // Reserved - 0x00, // Reserved - }; - - byte[] l = BinaryUtils.convert(len + 8, 2); - data[1] = l[0]; - data[2] = l[1]; - - return data; - - } - - /** - * Accessor method to write the AFP datastream for the Image Object - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - if (objectEnvironmentGroup != null) { - objectEnvironmentGroup.writeDataStream(os); - } - - if (imageSegment != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - imageSegment.writeDataStream(baos); - byte[] b = baos.toByteArray(); - int off = 0; - while (off < b.length) { - int len = Math.min(30000, b.length - off); - os.write(getIPDStart(len)); - os.write(b, off, len); - off += len; - } - } - - writeEnd(os); - - } - - /** - * Helper method to write the start of the Image Object. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xFB; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the Image Object. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xFB; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java b/src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java deleted file mode 100644 index 558a600a5..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The IM Image Output Control structured field specifies the position and - * orientation of the IM image object area and the mapping of the image points - * to presentation device pels. - * - */ -public class ImageOutputControl extends AbstractAFPObject { - - /** - * The orientation of the image - */ - private int orientation = 0; - - /** - * Specifies the offset, along the X-axis, of the IM image object area - * origin to the origin of the including page - */ - private int xCoord = 0; - - /** - * Specifies the offset, along the Y-axis, of the IM image object area - * origin to the origin of the including page - */ - private int yCoord = 0; - - /** - * Map an image point to a single presentation device - */ - private boolean singlePoint = true; - - /** - * Constructor for the ImageOutputControl The x parameter specifies the - * offset, along the X-axis, of the IM image object area origin to the - * origin of the including page and the y parameter specifies the offset - * along the Y-axis. The offset is specified in image points and is resolved - * using the units of measure specified for the image in the IID structured - * field. - * - * @param x - * The X-axis offset. - * @param y - * The Y-axis offset. - */ - public ImageOutputControl(int x, int y) { - - xCoord = x; - yCoord = y; - - } - - /** - * Accessor method to write the AFP datastream for the Image Output Control - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occured - */ - public void writeDataStream(OutputStream os) throws IOException { - - byte[] data = new byte[33]; - - data[0] = 0x5A; - data[1] = 0x00; - data[2] = 0x20; - data[3] = (byte) 0xD3; - data[4] = (byte) 0xA7; - data[5] = (byte) 0x7B; - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - - // XoaOset - byte[] x1 = BinaryUtils.convert(xCoord, 3); - data[9] = x1[0]; - data[10] = x1[1]; - data[11] = x1[2]; - - // YoaOset - byte[] x2 = BinaryUtils.convert(yCoord, 3); - data[12] = x2[0]; - data[13] = x2[1]; - data[14] = x2[2]; - - switch (orientation) { - case 0: - // 0 and 90 degrees respectively - data[15] = 0x00; - data[16] = 0x00; - data[17] = 0x2D; - data[18] = 0x00; - break; - case 90: - // 90 and 180 degrees respectively - data[15] = 0x2D; - data[16] = 0x00; - data[17] = 0x5A; - data[18] = 0x00; - break; - case 180: - // 180 and 270 degrees respectively - data[15] = 0x5A; - data[16] = 0x00; - data[17] = (byte) 0x87; - data[18] = 0x00; - break; - case 270: - // 270 and 0 degrees respectively - data[15] = (byte) 0x87; - data[16] = 0x00; - data[17] = 0x00; - data[18] = 0x00; - break; - default: - // 0 and 90 degrees respectively - data[15] = 0x00; - data[16] = 0x00; - data[17] = 0x2D; - data[18] = 0x00; - break; - - } - - // Constant Data - data[19] = 0x00; - data[20] = 0x00; - data[21] = 0x00; - data[22] = 0x00; - data[23] = 0x00; - data[24] = 0x00; - data[25] = 0x00; - data[26] = 0x00; - - if (singlePoint) { - data[27] = 0x03; - data[28] = (byte) 0xE8; - data[29] = 0x03; - data[30] = (byte) 0xE8; - } else { - data[27] = 0x07; - data[28] = (byte) 0xD0; - data[29] = 0x07; - data[30] = (byte) 0xD0; - } - - // Constant Data - data[31] = (byte) 0xFF; - data[32] = (byte) 0xFF; - - os.write(data); - - } - - /** - * Sets the orientation which specifies the amount of clockwise rotation of - * the IM image object area. - * - * @param orientation - * The orientation to set. - */ - public void setOrientation(int orientation) { - - if (orientation == 0 || orientation == 90 || orientation == 180 - || orientation == 270) { - this.orientation = orientation; - } else { - throw new IllegalArgumentException( - "The orientation must be one of the values 0, 90, 180, 270"); - } - } - - /** - * Sets the singlepoint, if true map an image point to a single presentation - * device pel in the IM image object area. If false map an image point to - * two presentation device pels in the IM image object area (double-dot) - * - * @param singlepoint - * Use the singlepoint basis when true. - */ - public void setSinglepoint(boolean singlepoint) { - singlePoint = singlepoint; - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ImageRasterData.java b/src/java/org/apache/fop/render/afp/modca/ImageRasterData.java deleted file mode 100644 index ca440a859..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageRasterData.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * Contains the image points that define the IM image raster pattern. - * - * A raster pattern is the array of presentation device pels that forms - * the image. The image data is uncompressed. Bits are grouped into - * bytes and are ordered from left to right within each byte. Each bit - * in the image data represents an image point and is mapped to - * presentation device pels as specified in the IOC structured field. - * A bit with value B'1' indicates a significant image point; a bit - * with value B'0' indicates an insignificant image point. - * Image points are recorded from left to right in rows that represents - * scan lines (X direction), and rows representing scan lines are - * recorded from top to bottom (Y direction). When the image is - * presented, all image points in a row are presented before any - * image points in the next sequential row are presented, and all rows - * have the same number of image points. If the total number of image - * points is not a multiple of 8, the last byte of the image data is - * padded to a byte boundary. The padding bits do not represent image - * points and are ignored by presentation devices. - */ -public class ImageRasterData extends AbstractAFPObject { - - /** - * The image raster data - */ - private byte[] rasterData; - - /** - * Constructor for the image raster data object - * @param data The raster image data - */ - public ImageRasterData(byte[] data) { - this.rasterData = data; - } - - /** - * Accessor method to write the AFP datastream for the Image Raster Data - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - - byte[] data = new byte[9]; - - data[0] = 0x5A; - - // The size of the structured field - byte[] x = BinaryUtils.convert(rasterData.length + 8, 2); - data[1] = x[0]; - data[2] = x[1]; - - data[3] = (byte) 0xD3; - data[4] = (byte) 0xEE; - data[5] = (byte) 0x7B; - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - - os.write(data); - os.write(rasterData); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ImageRasterPattern.java b/src/java/org/apache/fop/render/afp/modca/ImageRasterPattern.java deleted file mode 100644 index 373e50631..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageRasterPattern.java +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -/** - * Raster data is a grid of cells covering an area of interest. - * Each pixel, the smallest unit of information in the grid, displays - * a unique attribute. This static class generates raster data for different - * shades of grey (betweeen 0 and 16) the lower the number being the - * darker the shade. The image data dimensions are 64 x 8. - */ -public class ImageRasterPattern { - - /** - * The Raster Pattern for Greyscale 16 - */ - private static final byte[] GREYSCALE16 = new byte[] { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - }; - - /** - * The Raster Pattern for Greyscale 15 - */ - private static final byte[] GREYSCALE15 = new byte[] { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - }; - - /** - * The Raster Pattern for Greyscale 14 - */ - private static final byte[] GREYSCALE14 = new byte[] { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - }; - - - /** - * The Raster Pattern for Greyscale 13 - */ - private static final byte[] GREYSCALE13 = new byte[] { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - /** - * The Raster Pattern for Greyscale 12 - */ - private static final byte[] GREYSCALE12 = new byte[] { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - /** - * The Raster Pattern for Greyscale 11 - */ - private static final byte[] GREYSCALE11 = new byte[] { - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - /** - * The Raster Pattern for Greyscale 10 - */ - private static final byte[] GREYSCALE10 = new byte[] { - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - 0x44, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - /** - * The Raster Pattern for Greyscale 9 - */ - private static final byte[] GREYSCALE09 = new byte[] { - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - 0x11, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - /** - * The Raster Pattern for Greyscale 8 - */ - private static final byte[] GREYSCALE08 = new byte[] { - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - }; - - - /** - * The Raster Pattern for Greyscale 7 - */ - private static final byte[] GREYSCALE07 = new byte[] { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - }; - - - /** - * The Raster Pattern for Greyscale 6 - */ - private static final byte[] GREYSCALE06 = new byte[] { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - }; - - /** - * The Raster Pattern for Greyscale 5 - */ - private static final byte[] GREYSCALE05 = new byte[] { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xEE, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - }; - - - /** - * The Raster Pattern for Greyscale 4 - */ - private static final byte[] GREYSCALE04 = new byte[] { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xAA, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - }; - - /** - * The Raster Pattern for Greyscale 3 - */ - private static final byte[] GREYSCALE03 = new byte[] { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xBB, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - }; - - /** - * The Raster Pattern for Greyscale 2 - */ - private static final byte[] GREYSCALE02 = new byte[] { - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xDD, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - }; - - - /** - * The Raster Pattern for Greyscale 1 - */ - private static final byte[] GREYSCALE01 = new byte[] { - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - 0x77, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - }; - - - /** - * The Raster Pattern for Greyscale 00 - */ - private static final byte[] GREYSCALE00 = new byte[] { - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - (byte)0xFF, - }; - - /** - * Static method to return the raster image data for the - * grey scale specified. The scale should be between 0 (darkest) - * and 16 (lightest). - * @param greyscale The grey scale value (0 - 16) - * @return the raster data byte array for the given greyscale value - */ - public static byte[] getRasterData(int greyscale) { - - int repeat = 16; - - byte[] greypattern = new byte[32]; - byte[] rasterdata = new byte[32 * repeat]; - - switch (greyscale) { - case 0: - System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32); - break; - case 1: - System.arraycopy(GREYSCALE01, 0, greypattern, 0, 32); - break; - case 2: - System.arraycopy(GREYSCALE02, 0, greypattern, 0, 32); - break; - case 3: - System.arraycopy(GREYSCALE03, 0, greypattern, 0, 32); - break; - case 4: - System.arraycopy(GREYSCALE04, 0, greypattern, 0, 32); - break; - case 5: - System.arraycopy(GREYSCALE05, 0, greypattern, 0, 32); - break; - case 6: - System.arraycopy(GREYSCALE06, 0, greypattern, 0, 32); - break; - case 7: - System.arraycopy(GREYSCALE07, 0, greypattern, 0, 32); - break; - case 8: - System.arraycopy(GREYSCALE08, 0, greypattern, 0, 32); - break; - case 9: - System.arraycopy(GREYSCALE09, 0, greypattern, 0, 32); - break; - case 10: - System.arraycopy(GREYSCALE10, 0, greypattern, 0, 32); - break; - case 11: - System.arraycopy(GREYSCALE11, 0, greypattern, 0, 32); - break; - case 12: - System.arraycopy(GREYSCALE12, 0, greypattern, 0, 32); - break; - case 13: - System.arraycopy(GREYSCALE13, 0, greypattern, 0, 32); - break; - case 14: - System.arraycopy(GREYSCALE14, 0, greypattern, 0, 32); - break; - case 15: - System.arraycopy(GREYSCALE15, 0, greypattern, 0, 32); - break; - case 16: - System.arraycopy(GREYSCALE16, 0, greypattern, 0, 32); - break; - default : - System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32); - break; - } - - for (int i = 0; i < repeat; i++) { - System.arraycopy(greypattern, 0, rasterdata, i * 32, 32); - } - return rasterdata; - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java b/src/java/org/apache/fop/render/afp/modca/ImageSegment.java deleted file mode 100644 index 7d6cc18aa..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -/** - * An Image Segment is represented by a set of self-defining fields, fields - * that describe their own contents. It starts with a Begin Segment, and - * ends with an End Segment. - * - * Between the Begin Segment and End Segment is the image information to - * be processed, called the Image Content. - * - * Only one Image Content can exist within a single IOCA Image Segment. - */ -public class ImageSegment extends AbstractAFPObject { - - /** - * Default name for the object environment group - */ - private static final String DEFAULT_NAME = "IS01"; - - /** - * The name of the image segment - */ - private String name; - - /** - * The name of the image segment as EBCIDIC bytes - */ - private byte[] nameBytes; - - /** - * The ImageContent for the image segment - */ - private ImageContent imageContent = null; - - /** - * Default constructor for the ImageSegment. - */ - public ImageSegment() { - this(DEFAULT_NAME); - } - - /** - * Constructor for the image segment with the specified name, - * the name must be a fixed length of eight characters. - * @param name The name of the image. - */ - public ImageSegment(String name) { - - if (name.length() != 4) { - String msg = "Image segment name must be 4 characters long " + name; - log.error("Constructor:: " + msg); - throw new IllegalArgumentException(msg); - } - - this.name = name; - - try { - this.nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - } catch (UnsupportedEncodingException usee) { - this.nameBytes = name.getBytes(); - log.warn( - "Constructor:: UnsupportedEncodingException translating the name " - + name); - } - } - - /** - * Sets the image size parameters - * resolution, hsize and vsize. - * @param hresol The horizontal resolution of the image. - * @param vresol The vertical resolution of the image. - * @param hsize The horizontal size of the image. - * @param vsize The vertival size of the image. - */ - public void setImageSize(int hresol, int vresol, int hsize, int vsize) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageSize(hresol, vresol, hsize, vsize); - } - - /** - * Sets the image encoding. - * @param encoding The image encoding. - */ - public void setImageEncoding(byte encoding) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageEncoding(encoding); - } - - /** - * Sets the image compression. - * @param compression The image compression. - */ - public void setImageCompression(byte compression) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageCompression(compression); - } - - /** - * Sets the image IDE size. - * @param size The IDE size. - */ - public void setImageIDESize(byte size) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageIDESize(size); - } - - /** - * Sets the image IDE color model. - * @param colorModel the IDE color model. - */ - public void setImageIDEColorModel(byte colorModel) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageIDEColorModel(colorModel); - } - - /** - * Set the data of the image. - * @param data the image data - */ - public void setImageData(byte[] data) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageData(data); - } - - /** - * Accessor method to write the AFP datastream for the Image Segment - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - - writeStart(os); - - if (imageContent != null) { - imageContent.writeDataStream(os); - } - - writeEnd(os); - - } - - /** - * Helper method to write the start of the Image Segment. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - 0x70, // ID - 0x04, // Length - 0x00, // Name byte 1 - 0x00, // Name byte 2 - 0x00, // Name byte 3 - 0x00, // Name byte 4 - }; - - for (int i = 0; i < nameBytes.length; i++) { - - data[2 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the Image Segment. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) throws IOException { - - byte[] data = new byte[] { - 0x71, // ID - 0x00, // Length - }; - os.write(data); - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java b/src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java deleted file mode 100644 index 7dd210a1e..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * Describes the measurement characteristics of the image when it is created. - */ -public class ImageSizeParameter extends AbstractAFPObject { - - private int hRes = 0; - private int vRes = 0; - private int hSize = 0; - private int vSize = 0; - - /** - * Constructor for a ImageSizeParameter for the specified - * resolution, hsize and vsize. - * @param hresol The horizontal resolution of the image. - * @param vresol The vertical resolution of the image. - * @param hsize The horizontal size of the image. - * @param vsize The vertical size of the image. - */ - public ImageSizeParameter(int hresol, int vresol, int hsize, int vsize) { - this.hRes = hresol; - this.vRes = vresol; - this.hSize = hsize; - this.vSize = vsize; - } - - /** - * Accessor method to write the AFP datastream for the Image Size Parameter - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occured - */ - public void writeDataStream(OutputStream os) throws IOException { - byte[] data = new byte[] { - (byte)0x94, // ID = Image Size Parameter - 0x09, // Length - 0x00, // Unit base - 10 Inches - 0x00, // HRESOL - 0x00, // - 0x00, // VRESOL - 0x00, // - 0x00, // HSIZE - 0x00, // - 0x00, // VSIZE - 0x00, // - }; - - byte[] x = BinaryUtils.convert(hRes, 2); - data[3] = x[0]; - data[4] = x[1]; - - byte[] y = BinaryUtils.convert(vRes, 2); - data[5] = y[0]; - data[6] = y[1]; - - byte[] w = BinaryUtils.convert(hSize, 2); - data[7] = w[0]; - data[8] = w[1]; - - byte[] h = BinaryUtils.convert(vSize, 2); - data[9] = h[0]; - data[10] = h[1]; - - os.write(data); - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java b/src/java/org/apache/fop/render/afp/modca/IncludeObject.java deleted file mode 100644 index 890fdcd9d..000000000 --- a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * An Include Object structured field references an object on a page or overlay. - * It optionally contains parameters that identify the object and that specify - * presentation parameters such as object position, size, orientation, mapping, - * and default color. - * <p> - * Where the presentation parameters conflict with parameters specified in the - * object's environment group (OEG), the parameters in the Include Object - * structured field override. If the referenced object is a page segment, the - * IOB parameters override the corresponding environment group parameters on all - * data objects in the page segment. - * </p> - */ -public class IncludeObject extends AbstractNamedAFPObject { - - /** - * The object type - */ - private byte objectType = (byte) 0x92; - - /** - * The orientation on the include object - */ - private int orientation = 0; - - /** - * Constructor for the include object with the specified name, the name must - * be a fixed length of eight characters and is the name of the referenced - * object. - * - * @param name - * the name of the image - */ - public IncludeObject(String name) { - - super(name); - objectType = (byte) 0xFB; - - } - - /** - * Sets the orientation to use for the Include Object. - * - * @param orientation - * The orientation (0,90, 180, 270) - */ - public void setOrientation(int orientation) { - - if (orientation == 0 || orientation == 90 || orientation == 180 - || orientation == 270) { - this.orientation = orientation; - } else { - throw new IllegalArgumentException( - "The orientation must be one of the values 0, 90, 180, 270"); - } - - } - - /** - * Accessor method to write the AFP datastream for the Include Object - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[37]; - - data[0] = 0x5A; - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(36, 2); //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a IOB - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAF; - data[5] = (byte) 0xC3; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - data[9 + i] = nameBytes[i]; - } - - data[17] = 0x00; - data[18] = objectType; - - // XoaOset - data[20] = (byte) 0xFF; - data[21] = (byte) 0xFF; - data[22] = (byte) 0xFF; - - // YoaOset - data[23] = (byte) 0xFF; - data[24] = (byte) 0xFF; - data[25] = (byte) 0xFF; - - switch (orientation) { - case 90: - data[26] = 0x2D; - data[27] = 0x00; - data[28] = 0x5A; - data[29] = 0x00; - break; - case 180: - data[26] = 0x5A; - data[27] = 0x00; - data[28] = (byte) 0x87; - data[29] = 0x00; - break; - case 270: - data[26] = (byte) 0x87; - data[27] = 0x00; - data[28] = 0x00; - data[29] = 0x00; - break; - default: - data[26] = 0x00; - data[27] = 0x00; - data[28] = 0x2D; - data[29] = 0x00; - break; - } - - // XocaOset - data[30] = (byte) 0xFF; - data[31] = (byte) 0xFF; - data[32] = (byte) 0xFF; - - // YocaOset - data[33] = (byte) 0xFF; - data[34] = (byte) 0xFF; - data[35] = (byte) 0xFF; - - data[36] = 0x01; - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java b/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java deleted file mode 100644 index 7c52fe0a2..000000000 --- a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * - * The Include Page Overlay structured field references an overlay resource - * definition that is to be positioned on the page. A page overlay can be - * referenced at any time during the page state, but not during an object state. - * The overlay contains its own active environment group definition. - * - * Note: There is no need for the triplets, so I have ignored them. - * - * A real example of where this will be used is for static overlays, such as an - * address on the page. - * - */ -public class IncludePageOverlay extends AbstractNamedAFPObject { - - /** - * The x coordinate - */ - private int x = 0; - - /** - * The y coordinate - */ - private int y = 0; - - /** - * The orientation - */ - private int orientation = 0; - - /** - * Constructor for the Include Page Overlay - * @param overlayName Name of the page segment - * @param x The x position - * @param y The y position - * @param orientation The orientation - */ - public IncludePageOverlay(String overlayName, int x, int y, int orientation) { - super(overlayName); - this.x = x; - this.y = y; - setOrientation(orientation); - } - - /** - * Sets the orienation to use for the overlay. - * - * @param orientation - * The orientation (0,90, 180, 270) - */ - public void setOrientation(int orientation) { - if (orientation == 0 || orientation == 90 || orientation == 180 - || orientation == 270) { - this.orientation = orientation; - } else { - throw new IllegalArgumentException( - "The orientation must be one of the values 0, 90, 180, 270"); - } - } - - /** - * Accessor method to write the AFP datastream for the Include Page Overlay - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[25]; //(9 +16) - - data[0] = 0x5A; - - // Set the total record length - byte[] len = BinaryUtils.convert(24, 2); //Ignore first byte - data[1] = len[0]; - data[2] = len[1]; - - // Structured field ID for a IPO - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAF; - data[5] = (byte) 0xD8; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - data[9 + i] = nameBytes[i]; - } - - byte[] xcoord = BinaryUtils.convert(x, 3); - data[17] = xcoord[0]; // x coordinate - data[18] = xcoord[1]; - data[19] = xcoord[2]; - - byte[] ycoord = BinaryUtils.convert(y, 3); - data[20] = ycoord[0]; // y coordinate - data[21] = ycoord[1]; - data[22] = ycoord[2]; - - switch (orientation) { - case 90: - data[23] = 0x2D; - data[24] = 0x00; - break; - case 180: - data[23] = 0x5A; - data[24] = 0x00; - break; - case 270: - data[23] = (byte) 0x87; - data[24] = 0x00; - break; - default: - data[23] = 0x00; - data[24] = 0x00; - break; - } - os.write(data); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java b/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java deleted file mode 100644 index 7792a7162..000000000 --- a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Include Page Segment structured field references a page segment resource - * object that is to be presented on the page or overlay presentation space. The IPS - * specifies a reference point on the including page or overlay coordinate system that - * may be used to position objects contained in the page segment. A page segment - * can be referenced at any time during page or overlay state, but not during an - * object state. The page segment inherits the active environment group definition of - * the including page or overlay. - * - * Note : No use for Triplets. - * - * A 'real' example for where this will be used is for - * the dynamic placing of overlay objects, such as signatures - * that may have to be placed at different positions on a document. - * - */ -public class IncludePageSegment extends AbstractNamedAFPObject { - - /** - * The x position where we need to put this object on the page - */ - private byte[] x; - - /** - * The y position where we need to put this object on the page - */ - private byte[] y; - - /** - * Constructor for the Include Page Segment - * @param name Name of the page segment - * @param x The x position - * @param y The y position - */ - public IncludePageSegment(String name, int x, int y) { - - super(name); - this.x = BinaryUtils.convert(x, 3); - this.y = BinaryUtils.convert(y, 3); - - } - - /** - * Accessor method to write the AFP datastream for the Include Page Segment - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[23]; //(9 +14) - - data[0] = 0x5A; - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(22, 2); //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a IPS - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAF; - data[5] = (byte) 0x5F; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - data[9 + i] = nameBytes[i]; - } - - data[17] = x[0]; // x coordinate - data[18] = x[1]; - data[19] = x[2]; - - data[20] = y[0]; // y coordinate - data[21] = y[1]; - data[22] = y[2]; - - os.write(data); - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java b/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java deleted file mode 100644 index f38096ade..000000000 --- a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Invoke Medium Map structured field identifies the Medium Map that is to - * become active for the document. An Invoke Medium Map structured field affects - * the document's current environment. The Medium Map's effect on current environment - * parameter values lasts until a new Medium Map is invoked. - */ -public class InvokeMediumMap extends AbstractNamedAFPObject { - - /** - * Constructor for the Invoke Medium Map - * @param mediumMapName Name of the medium map - */ - public InvokeMediumMap(String mediumMapName) { - - super(mediumMapName); - - } - - /** - * Accessor method to write the AFP datastream for the Invoke Medium Map - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(16, 2); //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a IPO - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAB; - data[5] = (byte) 0xCC; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java deleted file mode 100644 index f0f372fcb..000000000 --- a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.Iterator; -import java.util.List; - -import org.apache.fop.render.afp.exceptions.FontRuntimeException; -import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.fonts.CharacterSet; -import org.apache.fop.render.afp.fonts.OutlineFont; -import org.apache.fop.render.afp.fonts.RasterFont; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Map Coded Font structured field maps a unique coded font resource local - * ID, which may be embedded one or more times within an object's data and - * descriptor, to the identifier of a coded font resource object. Additionally, - * the Map Coded Font structured field specifies a set of resource attributes - * for the coded font. - * - * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a> - */ -public class MapCodedFont extends AbstractAFPObject { - - /** - * The collection of map coded fonts (maximum of 254) - */ - private List fontList = null; - - /** - * Constructor for the MapCodedFont - */ - public MapCodedFont() { - - fontList = new java.util.ArrayList(); - - } - - /** - * Accessor method to write the AFP datastream for the Map Coded Font - * @param os The stream to write to - * @throws java.io.IOException an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - baos.write(0x5A); - baos.write(new byte[] {0x00, 0x00}); - - // Field identifier for a MapCodedFont - baos.write(new byte[] {(byte) 0xD3, (byte) 0xAB, (byte) 0x8A}); - - // Reserved - baos.write(new byte[] {0x00, 0x00, 0x00}); - - - Iterator iter = fontList.iterator(); - while (iter.hasNext()) { - - FontDefinition fd = (FontDefinition) iter.next(); - - // Start of repeating groups (occurs 1 to 254) - baos.write(0x00); - - if (fd.scale == 0) { - // Raster Font - baos.write(0x22); // Length of 34 - } else { - // Outline Font - baos.write(0x3A); // Length of 58 - } - - // Font Character Set Name Reference - baos.write(0x0C); - baos.write(0x02); - baos.write((byte) 0x86); - baos.write(0x00); - baos.write(fd.characterSet); - - // Font Code Page Name Reference - baos.write(0x0C); - baos.write(0x02); - baos.write((byte) 0x85); - baos.write(0x00); - baos.write(fd.codePage); - - // Character Rotation - baos.write(0x04); - baos.write(0x26); - baos.write(fd.orientation); - baos.write(0x00); - - // Resource Local Identifier - baos.write(0x04); - baos.write(0x24); - baos.write(0x05); - baos.write(fd.fontReferenceKey); - - if (fd.scale != 0) { - // Outline Font (triplet '1F') - baos.write(0x14); - baos.write(0x1F); - baos.write(0x00); - baos.write(0x00); - - baos.write(BinaryUtils.convert(fd.scale, 2)); // Height - baos.write(new byte[] {0x00, 0x00}); // Width - - baos.write(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}); - - baos.write(0x60); - - // Outline Font (triplet '5D') - baos.write(0x04); - baos.write(0x5D); - baos.write(BinaryUtils.convert(fd.scale, 2)); - } - - } - - byte[] data = baos.toByteArray(); - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(data.length - 1, 2); - data[1] = rl1[0]; - data[2] = rl1[1]; - - os.write(data); - - } - - /** - * Add a font definition on the the map coded font object. - * - * @param fontReference - * the font number used as the resource identifier - * @param font - * the font - * @param size - * the size of the font - * @param orientation - * the orientation of the font - * @throws MaximumSizeExceededException if the maximum number of fonts have been exceeded - */ - public void addFont(int fontReference, AFPFont font, int size, int orientation) - throws MaximumSizeExceededException { - - FontDefinition fd = new FontDefinition(); - - fd.fontReferenceKey = BinaryUtils.convert(fontReference)[0]; - - switch (orientation) { - case 90: - fd.orientation = 0x2D; - break; - case 180: - fd.orientation = 0x5A; - break; - case 270: - fd.orientation = (byte) 0x87; - break; - default: - fd.orientation = 0x00; - break; - } - - try { - - if (font instanceof RasterFont) { - - RasterFont raster = (RasterFont) font; - CharacterSet cs = raster.getCharacterSet(size); - if (cs == null) { - String msg = "Character set not found for font " - + font.getFontName() + " with point size " + size; - log.error(msg); - throw new FontRuntimeException(msg); - } - - fd.characterSet = cs.getNameBytes(); - - if (fd.characterSet.length != 8) { - throw new IllegalArgumentException("The character set " - + new String(fd.characterSet, - AFPConstants.EBCIDIC_ENCODING) - + " must have a fixed length of 8 characters."); - } - - fd.codePage = cs.getCodePage().getBytes( - AFPConstants.EBCIDIC_ENCODING); - - if (fd.codePage.length != 8) { - throw new IllegalArgumentException("The code page " - + new String(fd.codePage, - AFPConstants.EBCIDIC_ENCODING) - + " must have a fixed length of 8 characters."); - } - - } else if (font instanceof OutlineFont) { - - OutlineFont outline = (OutlineFont) font; - CharacterSet cs = outline.getCharacterSet(); - fd.characterSet = cs.getNameBytes(); - - // There are approximately 72 points to 1 inch or 20 1440ths per point. - - fd.scale = ((size / 1000) * 20); - - fd.codePage = cs.getCodePage().getBytes( - AFPConstants.EBCIDIC_ENCODING); - - if (fd.codePage.length != 8) { - throw new IllegalArgumentException("The code page " - + new String(fd.codePage, - AFPConstants.EBCIDIC_ENCODING) - + " must have a fixed length of 8 characters."); - } - - } else { - String msg = "Font of type " + font.getClass().getName() - + " not recognized."; - log.error(msg); - throw new FontRuntimeException(msg); - } - - if (fontList.size() > 253) { - - // Throw an exception if the size is exceeded - throw new MaximumSizeExceededException(); - - } else { - fontList.add(fd); - } - - } catch (UnsupportedEncodingException ex) { - - throw new FontRuntimeException("Failed to create font " - + " due to a UnsupportedEncodingException", ex); - - } - } - - /** - * Private utility class used as a container for font attributes - */ - private class FontDefinition { - - /** - * The code page of the font - */ - private byte[] codePage; - - /** - * The character set of the font - */ - private byte[] characterSet; - - /** - * The font reference key - */ - private byte fontReferenceKey; - - /** - * The orientation of the font - */ - private byte orientation; - - /** - * The scale (only specified for outline fonts) - */ - private int scale = 0; - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java deleted file mode 100644 index 129a3f5a1..000000000 --- a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.List; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Map Page Overlay structured field maps a Resource Local ID to the name of - * a Begin Overlay structured field. A Map Page Overlay structured field may - * contain from one to 254 repeating groups. - */ -public class MapPageOverlay extends AbstractAFPObject { - - /** - * The collection of overlays (maximum of 254 stored as byte[]) - */ - private List overLays = new java.util.ArrayList(); - - /** - * Constructor for the Map Page Overlay - */ - public MapPageOverlay() { - - } - - /** - * Add an overlay to to the map page overlay object. - * - * @param name - * The name of the overlay. - * @throws MaximumSizeExceededException if the maximum size is reached - */ - public void addOverlay(String name) throws MaximumSizeExceededException { - - if (overLays.size() > 253) { - throw new MaximumSizeExceededException(); - } - - if (name.length() != 8) { - throw new IllegalArgumentException("The name of overlay " + name - + " must be 8 characters"); - } - - if (log.isDebugEnabled()) { - log.debug("addOverlay():: adding overlay " + name); - } - - try { - byte[] data = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - overLays.add(data); - } catch (UnsupportedEncodingException usee) { - log.error("addOverlay():: UnsupportedEncodingException translating the name " - + name); - } - } - - /** - * Accessor method to write the AFP datastream for the Map Page Overlay - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - int oLayCount = overLays.size(); - int recordlength = oLayCount * 18; - - byte[] data = new byte[recordlength + 9]; - - data[0] = 0x5A; - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(recordlength + 8, 2); //Ignore the - // first byte in - // the length - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a MPO - data[3] = (byte) 0xD3; - data[4] = (byte) 0xAB; - data[5] = (byte) 0xD8; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - int pos = 8; - - //For each overlay - byte olayref = 0x00; - - for (int i = 0; i < oLayCount; i++) { - olayref = (byte) (olayref + 1); - - data[++pos] = 0x00; - data[++pos] = 0x12; //the length of repeating group - - data[++pos] = 0x0C; //Fully Qualified Name - data[++pos] = 0x02; - data[++pos] = (byte) 0x84; - data[++pos] = 0x00; - - //now add the name - byte[] name = (byte[]) overLays.get(i); - - for (int j = 0; j < name.length; j++) { - data[++pos] = name[j]; - } - - data[++pos] = 0x04; //Resource Local Identifier (RLI) - data[++pos] = 0x24; - data[++pos] = 0x02; - - //now add the unique id to the RLI - data[++pos] = olayref; - } - os.write(data); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/NoOperation.java b/src/java/org/apache/fop/render/afp/modca/NoOperation.java deleted file mode 100644 index 54515a070..000000000 --- a/src/java/org/apache/fop/render/afp/modca/NoOperation.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The No Operation structured field may be used to carry comments - * or any other type of unarchitected data. Although not recommended, - * it may also be used to carry semantic data in private or exchange data - * streams. However, because receivers of interchange data streams should - * ignore the content of No Operation structured fields and because - * receiver-generator products are not required to propagate - * No Operation structured fields, no semantics should be attached to - * the data carried by the No Operation structured field in interchange - */ -public class NoOperation extends AbstractAFPObject { - - /** Up to 32759 bytes of data with no architectural definition */ - private static final int MAX_DATA_LEN = 32759; - - /** - * Byte representation of the comment - */ - private String content; - - /** - * Construct a tag logical element with the name and value specified. - * - * @param content the content to record - */ - public NoOperation(String content) { - this.content = content; - } - - /** - * Accessor method to obtain the byte array AFP datastream for the - * NoOperation. - * - * @param os The outputsteam stream - * @throws java.io.IOException if an I/O exception occurs during processing - */ - public void writeDataStream(OutputStream os) throws IOException { - byte[] contentData = content.getBytes(AFPConstants.EBCIDIC_ENCODING); - int contentLen = contentData.length; - - // packet maximum of 32759 bytes - if (contentLen > MAX_DATA_LEN) { - contentLen = MAX_DATA_LEN; - } - - byte[] data = new byte[9 + contentLen]; - - data[0] = 0x5A; - - // Set the total record length - byte[] rl1 = BinaryUtils.convert(8 + contentLen, 2); - - //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a TLE - data[3] = (byte) 0xD3; - data[4] = (byte) 0xEE; - data[5] = (byte) 0xEE; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - int pos = 9; - for (int i = 0; i < contentLen; i++) { - data[pos++] = contentData[i]; - } - os.write(data); - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java deleted file mode 100644 index 561c8c6fe..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Object Area Descriptor structured field specifies the size and attributes - * of an object area presentation space. - * - */ -public class ObjectAreaDescriptor extends AbstractDescriptor { - - /** - * Construct an object area descriptor for the specified object width - * and object height. - * @param width The page width. - * @param height The page height. - * @param widthResolution The page width resolution. - * @param heightResolution The page height resolution. - */ - public ObjectAreaDescriptor(int width, int height, int widthResolution, int heightResolution) { - super(width, height, widthResolution, heightResolution); - } - - /** - * Accessor method to write the AFP datastream for the Object Area Descriptor - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[29]; - data[0] = 0x5A; - - byte[] len = BinaryUtils.convert(data.length - 1, 2); - data[1] = len[0]; // Length - data[2] = len[1]; - - data[3] = (byte) 0xD3; - data[4] = (byte) 0xA6; - data[5] = (byte) 0x6B; - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - data[9] = 0x03; // Triplet length - data[10] = 0x43; // tid = Descriptor Position Triplet - data[11] = 0x01; // DesPosId = 1 - data[12] = 0x08; // Triplet length - data[13] = 0x4B; // tid = Measurement Units Triplet - data[14] = 0x00; // XaoBase = 10 inches - data[15] = 0x00; // YaoBase = 10 inches - - // XaoUnits - byte[] xdpi = BinaryUtils.convert(widthResolution * 10, 2); - data[16] = xdpi[0]; - data[17] = xdpi[1]; - - // YaoUnits - byte[] ydpi = BinaryUtils.convert(heightResolution * 10, 2); - data[18] = ydpi[0]; - data[19] = ydpi[1]; - - data[20] = 0x09; // Triplet length - data[21] = 0x4C; // tid = Object Area Size - data[22] = 0x02; // Size Type - - byte[] x = BinaryUtils.convert(width, 3); - data[23] = x[0]; - data[24] = x[1]; - data[25] = x[2]; - - byte[] y = BinaryUtils.convert(height, 3); - data[26] = y[0]; - data[27] = y[1]; - data[28] = y[2]; - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java b/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java deleted file mode 100644 index e500c1269..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Object Area Position structured field specifies the origin and - * orientation of the object area, and the origin and orientation of the - * object content within the object area. - */ -public class ObjectAreaPosition extends AbstractAFPObject { - - private int _x = 0; - private int _y = 0; - private int _rot = 0; - - /** - * Construct an object area position for the specified object y, y position. - * @param x The x coordinate. - * @param y The y coordinate. - * @param rotation The coordinate system rotation (must be 0, 90, 180, 270). - */ - public ObjectAreaPosition(int x, int y, int rotation) { - - _x = x; - _y = y; - _rot = rotation; - } - - /** - * Accessor method to write the AFP datastream for the Object Area Position - * @param os The stream to write to - * @throws java.io.IOException - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - 0x5A, - 0x00, // Length - 0x20, // Length - (byte) 0xD3, - (byte) 0xAC, - (byte) 0x6B, - 0x00, // Flags - 0x00, // Reserved - 0x00, // Reserved - 0x01, // OAPosID = 1 - 0x17, // RGLength = 23 - 0x00, // XoaOSet - 0x00, - 0x00, - 0x00, // YoaOSet - 0x00, - 0x00, - (byte)(_rot / 2), // XoaOrent - 0x00, - (byte)(_rot / 2 + 45), // YoaOrent - 0x00, - 0x00, // Reserved - 0x00, // XocaOSet - 0x00, - 0x00, - 0x00, // YocaOSet - 0x00, - 0x00, - 0x00, // XocaOrent - 0x00, - 0x2D, // YocaOrent - 0x00, - 0x01, // RefCSys - }; - - byte[] l = BinaryUtils.convert(data.length - 1, 2); - data[1] = l[0]; - data[2] = l[1]; - - byte[] x = BinaryUtils.convert(_x, 3); - data[11] = x[0]; - data[12] = x[1]; - data[13] = x[2]; - - byte[] y = BinaryUtils.convert(_y, 3); - data[14] = y[0]; - data[15] = y[1]; - data[16] = y[2]; - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java deleted file mode 100644 index d6b029122..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; - - -/** - * An Object Environment Group (OEG) may be associated with an object and is contained - * within the object's begin-end envelope. - * The object environment group defines the object's origin and orientation on the page, - * and can contain font and color attribute table information. The scope of an object - * environment group is the scope of its containing object. - * - * An application that creates a data-stream document may omit some of the parameters - * normally contained in the object environment group, or it may specify that one or - * more default values are to be used. - */ -public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject { - - /** - * Default name for the object environment group - */ - private static final String DEFAULT_NAME = "OEG00001"; - - /** - * The ObjectAreaDescriptor for the object environment group - */ - private ObjectAreaDescriptor objectAreaDescriptor = null; - - /** - * The ObjectAreaPosition for the object environment group - */ - private ObjectAreaPosition objectAreaPosition = null; - - /** - * The ImageDataDescriptor for the object environment group - */ - private ImageDataDescriptor imageDataDescriptor = null; - - /** - * Default constructor for the ObjectEnvironmentGroup. - */ - public ObjectEnvironmentGroup() { - - this(DEFAULT_NAME); - - } - - /** - * Constructor for the ObjectEnvironmentGroup, this takes a - * name parameter which must be 8 characters long. - * @param name the object environment group name - */ - public ObjectEnvironmentGroup(String name) { - - super(name); - - } - - /** - * Sets the object area parameters. - * @param x the x position of the object - * @param y the y position of the object - * @param width the object width - * @param height the object height - * @param rotation the object orientation - * @param widthResolution the object resolution width - * @param heightResolution the object resolution height - */ - public void setObjectArea(int x, int y, int width, int height, int rotation, - int widthResolution, int heightResolution) { - - objectAreaDescriptor = new ObjectAreaDescriptor(width, height, - widthResolution, heightResolution); - objectAreaPosition = new ObjectAreaPosition(x, y, rotation); - - } - - /** - * Set the dimensions of the image. - * @param xresol the x resolution of the image - * @param yresol the y resolution of the image - * @param width the image width - * @param height the image height - */ - public void setImageData(int xresol, int yresol, int width, int height) { - imageDataDescriptor = new ImageDataDescriptor(xresol, yresol, width, height); - } - - /** - * Accessor method to obtain write the AFP datastream for - * the object environment group. - * @param os The stream to write to - * @throws java.io.IOException throw if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - - writeStart(os); - - objectAreaDescriptor.writeDataStream(os); - - objectAreaPosition.writeDataStream(os); - - if (imageDataDescriptor != null) { - imageDataDescriptor.writeDataStream(os); - } - - writeEnd(os); - - } - - /** - * Helper method to write the start of the object environment group. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[] { - 0x5A, // Structured field identifier - 0x00, // Length byte 1 - 0x10, // Length byte 2 - (byte) 0xD3, // Structured field id byte 1 - (byte) 0xA8, // Structured field id byte 2 - (byte) 0xC7, // Structured field id byte 3 - 0x00, // Flags - 0x00, // Reserved - 0x00, // Reserved - 0x00, // Name - 0x00, // - 0x00, // - 0x00, // - 0x00, // - 0x00, // - 0x00, // - 0x00, // - }; - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the object environment group. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xC7; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/Overlay.java b/src/java/org/apache/fop/render/afp/modca/Overlay.java deleted file mode 100644 index 3a4cdfb11..000000000 --- a/src/java/org/apache/fop/render/afp/modca/Overlay.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * An overlay is a MO:DCA-P resource object. - * - * It may be stored in an external resource library or it may be - * carried in a resource group. An overlay is similar to a page in - * that it defines its own environment and carries the same data objects. - */ -public class Overlay extends AbstractPageObject { - - /** - * Construct a new overlay object for the specified name argument, the overlay - * name should be an 8 character identifier. - * - * @param name - * the name of the page. - * @param width - * the width of the page. - * @param height - * the height of the page. - * @param rotation - * the rotation of the page. - * @param widthResolution - * the width resolution of the page. - * @param heightResolution - * the height resolution of the page. - */ - public Overlay(String name, int width, int height, int rotation, - int widthResolution, int heightResolution) { - - super(name, width, height, rotation, widthResolution, heightResolution); - - } - - /** - * Accessor method to write the AFP datastream for the overlay. - * - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - activeEnvironmentGroup.writeDataStream(os); - - writeObjectList(segments, os); - - writeObjectList(tagLogicalElements, os); - - writeObjectList(objects, os); - - writeEnd(os); - - } - - /** - * Helper method to write the start of the overlay. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xDF; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the overlay. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xDF; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java b/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java deleted file mode 100644 index 541df823e..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Page Descriptor structured field specifies the size and attributes of - * a page or overlay presentation space. - * - */ -public class PageDescriptor extends AbstractDescriptor { - - /** - * Construct a page descriptor for the specified page width - * and page height. - * @param width The page width. - * @param height The page height. - * @param widthResolution The page width resolution - * @param heightResolution The page height resolution - */ - public PageDescriptor(int width, int height, int widthResolution, int heightResolution) { - super(width, height, widthResolution, heightResolution); - } - - /** - * Accessor method to write the AFP datastream for the Page Descriptor - * @param os The stream to write to - * @throws java.io.IOException in the event that an I/O Exception occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - log.debug("width=" + width); - log.debug("height=" + height); - byte[] data = new byte[24]; - data[0] = 0x5A; - data[1] = 0x00; - data[2] = 0x17; - data[3] = (byte) 0xD3; - data[4] = (byte) 0xA6; - data[5] = (byte) 0xAF; - - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - data[9] = 0x00; // XpgBase = 10 inches - data[10] = 0x00; // YpgBase = 10 inches - - // XpgUnits - byte[] xdpi = BinaryUtils.convert(widthResolution * 10, 2); - data[11] = xdpi[0]; - data[12] = xdpi[1]; - - // YpgUnits - byte[] ydpi = BinaryUtils.convert(heightResolution * 10, 2); - data[13] = ydpi[0]; - data[14] = ydpi[1]; - - // XpgSize - byte[] x = BinaryUtils.convert(width, 3); - data[15] = x[0]; - data[16] = x[1]; - data[17] = x[2]; - - // YpgSize - byte[] y = BinaryUtils.convert(height, 3); - data[18] = y[0]; - data[19] = y[1]; - data[20] = y[2]; - - data[21] = 0x00; // Reserved - data[22] = 0x00; // Reserved - data[23] = 0x00; // Reserved - - os.write(data); - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PageGroup.java b/src/java/org/apache/fop/render/afp/modca/PageGroup.java deleted file mode 100644 index 0b40a83c5..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PageGroup.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * A page group is used in the data stream to define a named, logical grouping - * of sequential pages. Page groups are delimited by begin-end structured fields - * that carry the name of the page group. Page groups are defined so that the - * pages that comprise the group can be referenced or processed as a single - * entity. Page groups are often processed in stand-alone fashion; that is, they - * are indexed, retrieved, and presented outside the context of the containing - * document. - * - * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a> - */ -public class PageGroup extends AbstractNamedAFPObject { - - /** - * The pages contained within this group - */ - private List objects = new ArrayList(); - - /** - * The tag logical elements contained within this group - */ - private List tagLogicalElements = new ArrayList(); - - /** - * The page state - */ - private boolean complete = false; - - /** - * Constructor for the PageGroup. - * - * @param name - * the name of the page group - */ - public PageGroup(String name) { - - super(name); - - } - - /** - * Adds a page object to the group. - * - * @param page - * the page object to add - */ - public void addPage(PageObject page) { - - if (!objects.contains(page)) { - objects.add(page); - } - - } - - /** - * @return the name of the page group - */ - public String getName() { - return name; - } - - /** - * Creates a TagLogicalElement on the page. - * - * @param name - * the name of the tag - * @param value - * the value of the tag - */ - public void createTagLogicalElement(String name, String value) { - - TagLogicalElement tle = new TagLogicalElement(name, value); - tagLogicalElements.add(tle); - - } - - /** - * Creates an InvokeMediaMap on the page. - * - * @param name - * the name of the media map - */ - public void createInvokeMediumMap(String name) { - - InvokeMediumMap imm = new InvokeMediumMap(name); - objects.add(imm); - - } - - /** - * Method to mark the end of the page group. - */ - public void endPageGroup() { - - complete = true; - - } - - /** - * Returns an indication if the page group is complete - * @return whether or not this page group is complete or not - */ - public boolean isComplete() { - return complete; - } - - /** - * Accessor method to write the AFP datastream for the page group. - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - writeObjectList(tagLogicalElements, os); - - writeObjectList(objects, os); - - writeEnd(os); - - } - - /** - * Helper method to write the start of the page group. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xAD; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the page group. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xAD; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PageObject.java b/src/java/org/apache/fop/render/afp/modca/PageObject.java deleted file mode 100644 index 5b9a00a89..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PageObject.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; -import java.io.IOException; -import java.io.OutputStream; - - - -/** - * Pages contain the data objects that comprise a presentation document. Each - * page has a set of data objects associated with it. Each page within a - * document is independent from any other page, and each must establish its own - * environment parameters. - * - * The page is the level in the document component hierarchy that is used for - * printing or displaying a document's content. The data objects contained in - * the page envelope in the data stream are presented when the page is - * presented. Each data object has layout information associated with it that - * directs the placement and orientation of the data on the page. In addition, - * each page contains layout information that specifies the measurement units, - * page width, and page depth. - * - * A page is initiated by a begin page structured field and terminated by an end - * page structured field. Structured fields that define objects and active - * environment groups or that specify attributes of the page may be encountered - * in page state. - * - */ -public class PageObject extends AbstractPageObject { - - /** - * The resource group object - */ - private ResourceGroup resourceGroup = null; - - /** - * Construct a new page object for the specified name argument, the page - * name should be an 8 character identifier. - * - * @param name - * the name of the page. - * @param width - * the width of the page. - * @param height - * the height of the page. - * @param rotation - * the rotation of the page. - * @param widthResolution - * the width resolution of the page. - * @param heightResolution - * the height resolution of the page. - */ - public PageObject(String name, int width, int height, int rotation, - int widthResolution, int heightResolution) { - - super(name, width, height, rotation, widthResolution, heightResolution); - - } - - /** - * Adds an overlay to the page resources - * @param overlay the overlay to add - */ - public void addOverlay(Overlay overlay) { - if (resourceGroup == null) { - resourceGroup = new ResourceGroup(); - } - resourceGroup.addOverlay(overlay); - } - - /** - * Creates an IncludePageOverlay on the page. - * - * @param name - * the name of the overlay - * @param x - * the x position of the overlay - * @param y - * the y position of the overlay - * @param orientation - * the orientation required for the overlay - */ - public void createIncludePageOverlay(String name, int x, int y, int orientation) { - - IncludePageOverlay ipo = new IncludePageOverlay(name, x, y, orientation); - objects.add(ipo); - - } - - /** - * Accessor method to write the AFP datastream for the page. - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - if (resourceGroup != null) { - resourceGroup.writeDataStream(os); - } - - activeEnvironmentGroup.writeDataStream(os); - - writeObjectList(segments, os); - - writeObjectList(tagLogicalElements, os); - - writeObjectList(objects, os); - - writeEnd(os); - - } - - /** - * Helper method to write the start of the page. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xAF; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the page. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xAF; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java deleted file mode 100644 index 98beb96f7..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.awt.Color; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * Presentation text data contains the graphic characters and the control - * sequences necessary to position the characters within the object space. The - * data consists of: - graphic characters to be presented - control sequences - * that position them - modal control sequences that adjust the positions by - * small amounts - other functions causing text to be presented with differences - * in appearance. - * - * The graphic characters are expected to conform to a coded font representation - * so that they can be translated from the code point in the object data to the - * character in the coded font. The units of measure for linear displacements - * are derived from the PresentationTextDescriptor or from the hierarchical - * defaults. - * - * In addition to graphic character code points, Presentation Text data can - * contain embedded control sequences. These are strings of two or more bytes - * which signal an alternate mode of processing for the content of the current - * Presentation Text data. - * - */ -public class PresentationTextData extends AbstractAFPObject { - - /** - * The maximum size of the presentation text data. - */ - private static final int MAX_SIZE = 8192; - - /** - * The afp data relating to this presentaion text data. - */ - private ByteArrayOutputStream _baos = new ByteArrayOutputStream(1024); - - /** - * The current x coordinate. - */ - private int _currentXCoordinate = -1; - - /** - * The current y cooridnate - */ - private int _currentYCoordinate = -1; - - /** - * The current font - */ - private String _currentFont = ""; - - /** - * The current orientation - */ - private int _currentOrientation = 0; - - /** - * The current color - */ - private Color _currentColor = new Color(0, 0, 0); - - /** - * The current variable space increment - */ - private int _currentVariableSpaceCharacterIncrement = 0; - - /** - * The current inter character adjustment - */ - private int _currentInterCharacterAdjustment = 0; - - /** - * Default constructor for the PresentationTextData. - */ - public PresentationTextData() { - - this(false); - - } - - /** - * Constructor for the PresentationTextData, the boolean flag indicate - * whether the control sequence prefix should be set to indicate the start - * of a new control sequence. - * - * @param controlInd - * The control sequence indicator. - */ - public PresentationTextData(boolean controlInd) { - - _baos.write(new byte[] { 0x5A, // Structured field identifier - 0x00, // Record length byte 1 - 0x00, // Record length byte 2 - (byte) 0xD3, // PresentationTextData identifier byte 1 - (byte) 0xEE, // PresentationTextData identifier byte 2 - (byte) 0x9B, // PresentationTextData identifier byte 3 - 0x00, // Flag - 0x00, // Reserved - 0x00, // Reserved - }, 0, 9); - - if (controlInd) { - _baos.write(new byte[] { 0x2B, (byte) 0xD3 }, 0, 2); - } - - } - - /** - * The Set Coded Font Local control sequence activates a coded font and - * specifies the character attributes to be used. This is a modal control - * sequence. - * - * @param font - * The font local identifier. - * @param afpdata - * The output stream to which data should be written. - */ - private void setCodedFont(byte font, ByteArrayOutputStream afpdata) { - - // Avoid unnecessary specification of the font - if (String.valueOf(font).equals(_currentFont)) { - return; - } else { - _currentFont = String.valueOf(font); - } - - afpdata.write(new byte[] { 0x03, (byte) 0xF1, font, }, 0, 3); - - } - - /** - * Establishes the current presentation position on the baseline at a new - * I-axis coordinate, which is a specified number of measurement units from - * the B-axis. There is no change to the current B-axis coordinate. - * - * @param coordinate - * The coordinate for the inline move. - * @param afpdata - * The output stream to which data should be written. - */ - private void absoluteMoveInline(int coordinate, - ByteArrayOutputStream afpdata) { - - byte[] b = BinaryUtils.convert(coordinate, 2); - - afpdata.write(new byte[] { 0x04, (byte) 0xC7, b[0], b[1], }, 0, 4); - - _currentXCoordinate = coordinate; - - } - - /** - * Establishes the baseline and the current presentation position at a new - * B-axis coordinate, which is a specified number of measurement units from - * the I-axis. There is no change to the current I-axis coordinate. - * - * @param coordinate - * The coordinate for the baseline move. - * @param afpdata - * The output stream to which data should be written. - */ - private void absoluteMoveBaseline(int coordinate, - ByteArrayOutputStream afpdata) { - - byte[] b = BinaryUtils.convert(coordinate, 2); - - afpdata.write(new byte[] { 0x04, (byte) 0xD3, b[0], b[1], }, 0, 4); - - _currentYCoordinate = coordinate; - - } - - /** - * The Transparent Data control sequence contains a sequence of code points - * that are presented without a scan for embedded control sequences. - * - * @param data - * The text data to add. - * @param afpdata - * The output stream to which data should be written. - */ - private void addTransparentData(byte[] data, ByteArrayOutputStream afpdata) { - - // Calculate the length - int l = data.length + 2; - - if (l > 255) { - // Check that we are not exceeding the maximum length - throw new IllegalArgumentException( - "Transparent data is longer than 253 bytes: " + data); - } - - afpdata.write(new byte[] { BinaryUtils.convert(l)[0], (byte) 0xDB, }, - 0, 2); - - afpdata.write(data, 0, data.length); - - } - - /** - * Draws a line of specified length and specified width in the B-direction - * from the current presentation position. The location of the current - * presentation position is unchanged. - * - * @param length - * The length of the rule. - * @param width - * The width of the rule. - * @param afpdata - * The output stream to which data should be written. - */ - private void drawBaxisRule(int length, int width, - ByteArrayOutputStream afpdata) { - - afpdata.write(new byte[] { 0x07, // Length - (byte) 0xE7, // Type - }, 0, 2); - - // Rule length - byte[] data1 = BinaryUtils.shortToByteArray((short) length); - afpdata.write(data1, 0, data1.length); - // Rule width - byte[] data2 = BinaryUtils.shortToByteArray((short) width); - afpdata.write(data2, 0, data2.length); - // Rule width fraction - afpdata.write(0x00); - - } - - /** - * Draws a line of specified length and specified width in the I-direction - * from the current presentation position. The location of the current - * presentation position is unchanged. - * - * @param length - * The length of the rule. - * @param width - * The width of the rule. - * @param afpdata - * The output stream to which data should be written. - */ - private void drawIaxisRule(int length, int width, - ByteArrayOutputStream afpdata) { - - afpdata.write(new byte[] { 0x07, // Length - (byte) 0xE5, // Type - }, 0, 2); - - // Rule length - byte[] data1 = BinaryUtils.shortToByteArray((short) length); - afpdata.write(data1, 0, data1.length); - // Rule width - byte[] data2 = BinaryUtils.shortToByteArray((short) width); - afpdata.write(data2, 0, data2.length); - // Rule width fraction - afpdata.write(0x00); - - } - - /** - * Create the presentation text data for the byte array of data. - * - * @param fontNumber - * The font resource identifier. - * @param x - * The x coordinate for the text data. - * @param y - * The y coordinate for the text data. - * @param orientation - * The orientation of the text data. - * @param col - * The text color. - * @param vsci - * The variable space character increment. - * @param ica - * The inter character adjustment. - * @param data - * The text data to be created. - * @throws MaximumSizeExceededException - */ - public void createTextData(int fontNumber, int x, int y, int orientation, - Color col, int vsci, int ica, byte[] data) - throws MaximumSizeExceededException { - - ByteArrayOutputStream afpdata = new ByteArrayOutputStream(); - - if (_currentOrientation != orientation) { - setTextOrientation(orientation, afpdata); - _currentOrientation = orientation; - _currentXCoordinate = -1; - _currentYCoordinate = -1; - } - - // Avoid unnecessary specification of the Y co-ordinate - if (y != _currentYCoordinate) { - absoluteMoveBaseline(y, afpdata); - _currentXCoordinate = -1; - } - - // Avoid unnecessary specification of the X co-ordinate - if (x != _currentXCoordinate) { - absoluteMoveInline(x, afpdata); - } - - // Avoid unnecessary specification of the variable space increment - if (vsci != _currentVariableSpaceCharacterIncrement) { - setVariableSpaceCharacterIncrement(vsci, afpdata); - _currentVariableSpaceCharacterIncrement = vsci; - } - - // Avoid unnecessary specification of the inter character adjustment - if (ica != _currentInterCharacterAdjustment) { - setInterCharacterAdjustment(ica, afpdata); - _currentInterCharacterAdjustment = ica; - } - - // Avoid unnecessary specification of the text color - if (!col.equals(_currentColor)) { - setExtendedTextColor(col, afpdata); - _currentColor = col; - } - - setCodedFont(BinaryUtils.convert(fontNumber)[0], afpdata); - addTransparentData(data, afpdata); - _currentXCoordinate = -1; - - int s = afpdata.size(); - - if (_baos.size() + s > MAX_SIZE) { - _currentXCoordinate = -1; - _currentYCoordinate = -1; - throw new MaximumSizeExceededException(); - } - - byte[] outputdata = afpdata.toByteArray(); - _baos.write(outputdata, 0, outputdata.length); - - } - - /** - * Drawing of lines using the starting and ending coordinates, thickness and - * colour arguments. - * - * @param x1 - * The starting X coordinate. - * @param y1 - * The starting Y coordinate. - * @param x2 - * The ending X coordinate. - * @param y2 - * The ending Y coordinate. - * @param thickness - * The line thickness. - * @param orientation - * The orientation of the text data. - * @param col - * The text color. - */ - public void createLineData(int x1, int y1, int x2, int y2, int thickness, - int orientation, Color col) throws MaximumSizeExceededException { - - ByteArrayOutputStream afpdata = new ByteArrayOutputStream(); - - if (_currentOrientation != orientation) { - setTextOrientation(orientation, afpdata); - _currentOrientation = orientation; - } - - // Avoid unnecessary specification of the Y coordinate - if (y1 != _currentYCoordinate) { - absoluteMoveBaseline(y1, afpdata); - } - - // Avoid unnecessary specification of the X coordinate - if (x1 != _currentXCoordinate) { - absoluteMoveInline(x1, afpdata); - } - - if (!col.equals(_currentColor)) { - setExtendedTextColor(col, afpdata); - _currentColor = col; - } - - if (y1 == y2) { - drawIaxisRule(x2 - x1, thickness, afpdata); - } else if (x1 == x2) { - drawBaxisRule(y2 - y1, thickness, afpdata); - } else { - return; - } - - int s = afpdata.size(); - - if (_baos.size() + s > MAX_SIZE) { - _currentXCoordinate = -1; - _currentYCoordinate = -1; - throw new MaximumSizeExceededException(); - } - - byte[] outputdata = afpdata.toByteArray(); - _baos.write(outputdata, 0, outputdata.length); - - } - - /** - * The Set Text Orientation control sequence establishes the I-direction and - * B-direction for the subsequent text. This is a modal control sequence. - * - * Semantics: This control sequence specifies the I-axis and B-axis - * orientations with respect to the Xp-axis for the current Presentation - * Text object. The orientations are rotational values expressed in degrees - * and minutes. - * - * @param orientation - * The text orientation (0,90, 180, 270). - * @param afpdata - * The output stream to which data should be written. - */ - private void setTextOrientation(int orientation, - ByteArrayOutputStream afpdata) { - - afpdata.write(new byte[] { 0x06, (byte) 0xF7, }, 0, 2); - - switch (orientation) { - case 90: - afpdata.write(0x2D); - afpdata.write(0x00); - afpdata.write(0x5A); - afpdata.write(0x00); - break; - case 180: - afpdata.write(0x5A); - afpdata.write(0x00); - afpdata.write(0x87); - afpdata.write(0x00); - break; - case 270: - afpdata.write(0x87); - afpdata.write(0x00); - afpdata.write(0x00); - afpdata.write(0x00); - break; - default: - afpdata.write(0x00); - afpdata.write(0x00); - afpdata.write(0x2D); - afpdata.write(0x00); - break; - } - - } - - /** - * The Set Extended Text Color control sequence specifies a color value and - * defines the color space and encoding for that value. The specified color - * value is applied to foreground areas of the text presentation space. - * This is a modal control sequence. - * - * @param col - * The color to be set. - * @param afpdata - * The output stream to which data should be written. - */ - private void setExtendedTextColor(Color col, - ByteArrayOutputStream afpdata) { - - afpdata.write(new byte[] { - 15 // Control sequence length - , (byte)0x81 // Control sequence function type - , 0x00 // Reserved; must be zero - , 0x01 // Color space - 0x01 = RGB - , 0x00 // Reserved; must be zero - , 0x00 // Reserved; must be zero - , 0x00 // Reserved; must be zero - , 0x00 // Reserved; must be zero - , 8 // Number of bits in component 1 - , 8 // Number of bits in component 2 - , 8 // Number of bits in component 3 - , 0 // Number of bits in component 4 - , (byte)(col.getRed()) // Red intensity - , (byte)(col.getGreen()) // Green intensity - , (byte)(col.getBlue()) // Blue intensity - }, 0, 15); - - } - - /** - * //TODO - * This is a modal control sequence. - * - * @param incr - * The increment to be set. - * @param afpdata - * The output stream to which data should be written. - */ - private void setVariableSpaceCharacterIncrement(int incr, - ByteArrayOutputStream afpdata) { - - byte[] b = BinaryUtils.convert(incr, 2); - - afpdata.write(new byte[] { - 4 // Control sequence length - , (byte)0xC5 // Control sequence function type - , b[0] - , b[1] - }, 0, 4); - - } - - /** - * //TODO - * This is a modal control sequence. - * - * @param incr - * The increment to be set. - * @param afpdata - * The output stream to which data should be written. - */ - private void setInterCharacterAdjustment(int incr, - ByteArrayOutputStream afpdata) { - - byte[] b = BinaryUtils.convert(Math.abs(incr), 2); - - afpdata.write(new byte[] { - 5 // Control sequence length - , (byte)0xC3 // Control sequence function type - , b[0] - , b[1] - , (byte)(incr >= 0 ? 0 : 1) // Direction - }, 0, 5); - - } - - /** - * Accessor method to write the AFP datastream for - * the text data. - * @param os The stream to write to - * @throws java.io.IOException - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = _baos.toByteArray(); - byte[] size = BinaryUtils.convert(data.length - 1, 2); - data[1] = size[0]; - data[2] = size[1]; - - os.write(data); - - } - - /** - * A control sequence is a sequence of bytes that specifies a control - * function. A control sequence consists of a control sequence introducer - * and zero or more parameters. The control sequence can extend multiple - * presentation text data objects, but must eventually be terminated. This - * method terminates the control sequence. - * - * @throws MaximumSizeExceededException - */ - public void endControlSequence() throws MaximumSizeExceededException { - - byte[] data = new byte[2]; - data[0] = 0x02; - data[1] = (byte) 0xF8; - - if (data.length + _baos.size() > MAX_SIZE) { - throw new MaximumSizeExceededException(); - } - - _baos.write(data, 0, data.length); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java deleted file mode 100644 index 3858f4169..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * The Presentation Text Descriptor specifies the units of measure for the - * Presentation Text object space, the size of the Presentation Text object - * space, and the initial values for modal parameters, called initial text - * conditions. Initial values not provided are defaulted by the controlling - * environment or the receiving device. - * - * The Presentation Text Descriptor provides the following initial values: - * - Unit base - * - Xp-units per unit base - * - Yp-units per unit base - * - Xp-extent of the presentation space - * - Yp-extent of the presentation space - * - Initial text conditions. - * - * The initial text conditions are values provided by the Presentation Text - * Descriptor to initialize the modal parameters of the control sequences. - * Modal control sequences typically are characterized by the word set in - * the name of the control sequence. Modal parameters are identified as such - * in their semantic descriptions. - * - */ -public class PresentationTextDescriptor extends AbstractDescriptor { - - /** - * Constructor a PresentationTextDescriptor for the specified - * width and height. - * @param width The width of the page. - * @param height The height of the page. - * @param widthResolution The width resolution of the page. - * @param heightResolution The height resolution of the page. - */ - public PresentationTextDescriptor(int width, int height, - int widthResolution, int heightResolution) { - super(width, height, widthResolution, heightResolution); - } - - /** - * Accessor method to write the AFP datastream for the Presentation Text Descriptor - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - byte[] data = new byte[23]; - data[0] = 0x5A; - data[1] = 0x00; - data[2] = 0x16; - data[3] = (byte) 0xD3; - data[4] = (byte) 0xB1; - data[5] = (byte) 0x9B; - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - - byte[] xdpi = BinaryUtils.convert(widthResolution * 10, 2); - data[11] = xdpi[0]; // xdpi - data[12] = xdpi[1]; - - byte[] ydpi = BinaryUtils.convert(heightResolution * 10, 2); - data[13] = ydpi[0]; // ydpi - data[14] = ydpi[1]; - - byte[] x = BinaryUtils.convert(width, 3); - data[15] = x[0]; - data[16] = x[1]; - data[17] = x[2]; - - byte[] y = BinaryUtils.convert(height, 3); - data[18] = y[0]; - data[19] = y[1]; - data[20] = y[2]; - - data[21] = 0x00; - data[22] = 0x00; - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java deleted file mode 100644 index c0f06439e..000000000 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.awt.Color; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; - -/** - * The Presentation Text object is the data object used in document processing - * environments for representing text which has been prepared for presentation. - * Text, as used here, means an ordered string of characters, such as graphic - * symbols, numbers, and letters, that are suitable for the specific purpose of - * representing coherent information. Text which has been prepared for - * presentation has been reduced to a primitive form through explicit - * specification of the characters and their placement in the presentation - * space. Control sequences which designate specific control functions may be - * embedded within the text. These functions extend the primitive form by - * applying specific characteristics to the text when it is presented. The - * collection of the graphic characters and control codes is called Presentation - * Text, and the object that contains the Presentation Text is called the - * PresentationText object. - * - */ -public class PresentationTextObject extends AbstractNamedAFPObject { - - /** - * Default name for the presentation text object - */ - private static final String DEFAULT_NAME = "PTO00001"; - - private PresentationTextData currentPresentationTextData = null; - - private ArrayList presentationTextData = new ArrayList(); - - /** - * Default constructor for the PresentationTextObject - */ - public PresentationTextObject() { - - this(DEFAULT_NAME); - - } - - /** - * Construct a new PresentationTextObject for the specified name argument, - * the name should be an 8 character identifier. - * @param name the name of this presentation object - */ - public PresentationTextObject(String name) { - - super(name); - - } - - /** - * Create the presentation text data for the byte array of data. - * - * @param fontNumber - * The font resource identifier. - * @param x - * The x coordinate for the text data. - * @param y - * The y coordinate for the text data. - * @param col - * The text color. - * @param vsci - * The variable space character increment. - * @param ica - * The inter character increment. - * @param data - * The text data to be created. - */ - public void createTextData(int fontNumber, int x, int y, Color col, - int vsci, int ica, byte[] data) { - - // Use a default orientation of zero - createTextData(fontNumber, x, y, 0, col, vsci, ica, data); - - } - - /** - * Create the presentation text data for the byte array of data. - * - * @param fontNumber - * The font resource identifier. - * @param x - * The x coordinate for the text data. - * @param y - * The y coordinate for the text data. - * @param orientation - * The orientation of the text data. - * @param col - * The text color. - * @param vsci - * The variable space character increment. - * @param ica - * The inter character adjustment. - * @param data - * The text data to be created. - */ - public void createTextData(int fontNumber, int x, int y, int orientation, - Color col, int vsci, int ica, byte[] data) { - - if (currentPresentationTextData == null) { - startPresentationTextData(); - } - - try { - - currentPresentationTextData.createTextData(fontNumber, x, y, - orientation, col, vsci, ica, data); - - } catch (MaximumSizeExceededException msee) { - - endPresentationTextData(); - createTextData(fontNumber, x, y, orientation, col, vsci, ica, data); - - } - - } - - /** - * Drawing of lines using the starting and ending coordinates, thickness. - * - * @param x1 - * The first x coordinate of the line. - * @param y1 - * The first y coordinate of the line. - * @param x2 - * The second x coordinate of the line. - * @param y2 - * The second y coordinate of the line. - * @param thickness - * The thickness of the line. - * @param col - * The text color. - */ - public void createLineData(int x1, int y1, int x2, int y2, int thickness, Color col) { - // Default orientation - createLineData(x1, y1, x2, y2, thickness, 0, col); - } - - /** - * Drawing of lines using the starting and ending coordinates, thickness and - * orientation arguments. - * - * @param x1 - * The first x coordinate of the line. - * @param y1 - * The first y coordinate of the line. - * @param x2 - * The second x coordinate of the line. - * @param y2 - * The second y coordinate of the line. - * @param thickness - * The thickness of the line. - * @param orientation - * The orientation of the line. - * @param col - * The text color. - */ - public void createLineData(int x1, int y1, int x2, int y2, int thickness, - int orientation, Color col) { - - if (currentPresentationTextData == null) { - startPresentationTextData(); - } - - try { - - currentPresentationTextData.createLineData(x1, y1, x2, y2, - thickness, orientation, col); - - } catch (MaximumSizeExceededException msee) { - - endPresentationTextData(); - createLineData(x1, y1, x2, y2, thickness, orientation, col); - - } - - } - - /** - * Helper method to mark the start of the presentation text data - */ - private void startPresentationTextData() { - - if (presentationTextData.size() == 0) { - currentPresentationTextData = new PresentationTextData(true); - } else { - currentPresentationTextData = new PresentationTextData(); - } - - presentationTextData.add(currentPresentationTextData); - - } - - /** - * Helper method to mark the end of the presentation text data - */ - private void endPresentationTextData() { - - currentPresentationTextData = null; - - } - - /** - * Accessor method to write the AFP datastream for the PresentationTextObject. - * @param os The stream to write to - * @throws java.io.IOException thrown if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - writeObjectList(presentationTextData, os); - - writeEnd(os); - - } - - /** - * Returns the name of this presentation text object - * @return the name of this presentation text object - */ - public String getName() { - - return name; - - } - - /** - * Helper method to write the start of the presenation text object. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0x9B; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the presenation text object. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0x9B; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * A control sequence is a sequence of bytes that specifies a control - * function. A control sequence consists of a control sequence introducer - * and zero or more parameters. The control sequence can extend multiple - * presentation text data objects, but must eventually be terminated. This - * method terminates the control sequence. - */ - public void endControlSequence() { - - if (currentPresentationTextData == null) { - startPresentationTextData(); - } - - try { - - currentPresentationTextData.endControlSequence(); - - } catch (MaximumSizeExceededException msee) { - - endPresentationTextData(); - endControlSequence(); - - } - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java deleted file mode 100644 index 07043dcf1..000000000 --- a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * A Resource Group contains a set of overlays. - */ -public final class ResourceGroup extends AbstractNamedAFPObject { - - /** - * Default name for the resource group - */ - private static final String DEFAULT_NAME = "RG000001"; - - - /** - * The overlays contained in this resource group - */ - private List overlays = new ArrayList(); - - /** - * Default constructor - */ - public ResourceGroup() { - - this(DEFAULT_NAME); - - } - - /** - * Constructor for the ResourceGroup, this takes a - * name parameter which must be 8 characters long. - * @param name the resource group name - */ - public ResourceGroup(String name) { - - super(name); - - } - - /** - * Adds an overlay to the resource group - * @param overlay the overlay to add - */ - public void addOverlay(Overlay overlay) { - overlays.add(overlay); - } - - /** - * Returns the list of overlays - * @return the list of overlays - */ - public List getOverlays() { - return overlays; - } - - /** - * Accessor method to obtain write the AFP datastream for - * the resource group. - * @param os The stream to write to - * @throws java.io.IOException if an I/O exception of some sort has occurred - */ - public void writeDataStream(OutputStream os) - throws IOException { - - writeStart(os); - - writeObjectList(overlays, os); - - writeEnd(os); - - } - - /** - * Helper method to write the start of the resource group. - * @param os The stream to write to - */ - private void writeStart(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA8; // Structured field id byte 2 - data[5] = (byte) 0xC6; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - - /** - * Helper method to write the end of the resource group. - * @param os The stream to write to - */ - private void writeEnd(OutputStream os) - throws IOException { - - byte[] data = new byte[17]; - - data[0] = 0x5A; // Structured field identifier - data[1] = 0x00; // Length byte 1 - data[2] = 0x10; // Length byte 2 - data[3] = (byte) 0xD3; // Structured field id byte 1 - data[4] = (byte) 0xA9; // Structured field id byte 2 - data[5] = (byte) 0xC6; // Structured field id byte 3 - data[6] = 0x00; // Flags - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - for (int i = 0; i < nameBytes.length; i++) { - - data[9 + i] = nameBytes[i]; - - } - - os.write(data); - - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java b/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java deleted file mode 100644 index 937f2019a..000000000 --- a/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; - -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * A Tag Logical Element structured field assigns an attribute name and an - * attribute value to a page or page group. The Tag Logical Element structured - * field may be embedded directly in the page or page group, or it may reference - * the page or page group from a document index. When a Tag Logical Element - * structured field references a page or is embedded in a page following the - * active environment group, it is associated with the page. When a Tag Logical - * Element structured field references a page group or is embedded in a page - * group following the Begin Named Page Group structured field, it is associated - * with the page group. When a Tag Logical Element structured field is associated - * with a page group, the parameters of the Tag Logical Element structured field - * are inherited by all pages in the page group and by all other page groups - * that are nested in the page group. The scope of a Tag Logical Element is - * determined by its position with respect to other TLEs that reference, or are - * embedded in, the same page or page group. The Tag Logical Element structured - * field does not provide any presentation specifications and therefore has no - * effect on the appearance of a document when it is presented. - * <p/> - */ -public class TagLogicalElement extends AbstractAFPObject { - - /** - * Name of the key, used within the TLE - */ - private String tleName = null; - - /** - * Value returned by the key - */ - private String tleValue = null; - - /** - * Byte representaion of the name - */ - private byte[] tleByteName = null; - - /** - * Byte representaion of the value - */ - private byte[] tleByteValue = null; - - /** - * Construct a tag logical element with the name and value specified. - * @param name the name of the tag logical element - * @param value the value of the tag logical element - */ - public TagLogicalElement(String name, String value) { - - this.tleName = name; - this.tleValue = value; - - try { - - this.tleByteName = name.getBytes(AFPConstants.EBCIDIC_ENCODING); - this.tleByteValue = value.getBytes(AFPConstants.EBCIDIC_ENCODING); - - } catch (UnsupportedEncodingException usee) { - - this.tleByteName = name.getBytes(); - this.tleByteValue = value.getBytes(); - log.warn( - "Constructor:: UnsupportedEncodingException translating the name " - + name); - - } - - } - - /** - * Accessor method to obtain the byte array AFP datastream for the - * TagLogicalElement. - * @param os The outputsteam stream - * @throws java.io.IOException if an I/O exception occurred - */ - public void writeDataStream(OutputStream os) throws IOException { - - byte[] data = new byte[17 + tleName.length() + tleValue.length()]; - - data[0] = 0x5A; - // Set the total record length - byte[] rl1 - = BinaryUtils.convert(16 + tleName.length() + tleValue.length(), 2); - //Ignore first byte - data[1] = rl1[0]; - data[2] = rl1[1]; - - // Structured field ID for a TLE - data[3] = (byte) 0xD3; - data[4] = (byte) 0xA0; - data[5] = (byte) 0x90; - - data[6] = 0x00; // Reserved - data[7] = 0x00; // Reserved - data[8] = 0x00; // Reserved - - //Use 2 triplets, attrubute name and value (the key for indexing) - - byte[] rl2 = BinaryUtils.convert(tleName.length() + 4, 1); - data[9] = rl2[0]; // length of the triplet, including this field - data[10] = 0x02; //Identifies it as a FQN triplet - data[11] = 0x0B; // GID format - data[12] = 0x00; - - int pos = 13; - for (int i = 0; i < tleByteName.length; i++) { - data[pos++] = tleByteName[i]; - } - - byte[] rl3 = BinaryUtils.convert(tleByteValue.length + 4, 1); - data[pos++] = rl3[0]; // length of the triplet, including this field - data[pos++] = 0x36; //Identifies the triplet, attribute value - data[pos++] = 0x00; // Reserved - data[pos++] = 0x00; // Reserved - - for (int i = 0; i < tleByteValue.length; i++) { - data[pos++] = tleByteValue[i]; - } - os.write(data); - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/TagLogicalElementBean.java b/src/java/org/apache/fop/render/afp/modca/TagLogicalElementBean.java deleted file mode 100644 index 29ac9eb5d..000000000 --- a/src/java/org/apache/fop/render/afp/modca/TagLogicalElementBean.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.modca; - -/** - * The TagLogicalElementBean provides a bean for holding the attributes of - * a tag logical element as key value pairs. - * <p/> - */ -public class TagLogicalElementBean { - - /** The key attribute */ - private String key; - - /** The value attribute */ - private String value; - - /** - * Constructor for the TagLogicalElementBean. - * @param key the key attribute - * @param value the value attribute - */ - public TagLogicalElementBean(String key, String value) { - this.key = key; - this.value = value; - } - - /** - * Getter for the key attribute. - * @return the key - */ - public String getKey() { - return key; - } - - /** - * Getter for the value attribute. - * @return the value - */ - public String getValue() { - return value; - } - -} diff --git a/src/java/org/apache/fop/render/afp/package.html b/src/java/org/apache/fop/render/afp/package.html new file mode 100644 index 000000000..3e611d964 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ --> +<HTML> +<TITLE>org.apache.fop.render.afp Package</TITLE> +<BODY> +<P>An AFP Renderer implementation and supporting classes.</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/tools/BinaryUtils.java b/src/java/org/apache/fop/render/afp/tools/BinaryUtils.java deleted file mode 100644 index 31ba45bcf..000000000 --- a/src/java/org/apache/fop/render/afp/tools/BinaryUtils.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.tools; - -import java.io.ByteArrayOutputStream; - -/** - * Library of utility useful conversion methods. - * - */ -public final class BinaryUtils { - - /** - * Convert an int into the corresponding byte array by encoding each - * two hexadecimal digits as a char. This will return a byte array - * to the length specified by bufsize. - * @param integer The int representation. - * @param bufsize The required byte array size. - * @return the hexadecimal digits as a byte array - */ - public static byte[] convert(int integer, int bufsize) { - StringBuffer buf = new StringBuffer(Integer.toHexString(integer)); - //Convert to an even number of digits - if (buf.length() % 2 != 0) { - buf.insert(0, "0"); - } - int size = buf.length() / 2; - if (size > bufsize) { - buf.delete(0, buf.length() - (bufsize * 2)); - } else { - while (size < bufsize) { - buf.insert(0, "00"); - size++; - } - } - return convert(buf.toString()); - } - - /** - * Convert an int into the corresponding byte array by encoding each - * two hexadecimal digits as a char. - * @param integer The int representation - * @return the hexadecimal digits as a byte array - */ - public static byte[] convert(int integer) { - return convert(Integer.toHexString(integer)); - } - - /** - * Convert a String of hexadecimal digits into the corresponding - * byte array by encoding each two hexadecimal digits as a byte. - * @param digits The hexadecimal digits representation. - * @return the hexadecimal digits as a byte array - */ - public static byte[] convert(String digits) { - - if (digits.length() % 2 == 0) { - // Even number of digits, so ignore - } else { - // Convert to an even number of digits - digits = "0" + digits; - } - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int i = 0; i < digits.length(); i += 2) { - char c1 = digits.charAt(i); - char c2 = digits.charAt(i + 1); - byte b = 0; - if ((c1 >= '0') && (c1 <= '9')) { - b += ((c1 - '0') * 16); - } else if ((c1 >= 'a') && (c1 <= 'f')) { - b += ((c1 - 'a' + 10) * 16); - } else if ((c1 >= 'A') && (c1 <= 'F')) { - b += ((c1 - 'A' + 10) * 16); - } else { - throw new IllegalArgumentException("Bad hexadecimal digit"); - } - - if ((c2 >= '0') && (c2 <= '9')) { - b += (c2 - '0'); - } else if ((c2 >= 'a') && (c2 <= 'f')) { - b += (c2 - 'a' + 10); - } else if ((c2 >= 'A') && (c2 <= 'F')) { - b += (c2 - 'A' + 10); - } else { - throw new IllegalArgumentException("Bad hexadecimal digit"); - } - baos.write(b); - } - return (baos.toByteArray()); - } - - /** - * Convert the specified short into a byte array. - * @param value The value to be converted. - * @param array The array to receive the data. - * @param offset The offset into the byte array for the start of the value. - */ - public static void shortToByteArray( - short value, - byte[] array, - int offset) { - array[offset] = (byte) (value >>> 8); - array[offset + 1] = (byte) value; - } - - /** - * Convert the specified short into a byte array. - * @param value The value to be converted. - * @return The byte array - */ - public static byte[] shortToByteArray(short value) { - byte[] serverValue = new byte[2]; - shortToByteArray(value, serverValue, 0); - return serverValue; - } - -} diff --git a/src/java/org/apache/fop/render/afp/tools/DTDEntityResolver.java b/src/java/org/apache/fop/render/afp/tools/DTDEntityResolver.java deleted file mode 100644 index e9554ecea..000000000 --- a/src/java/org/apache/fop/render/afp/tools/DTDEntityResolver.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.tools; - -import java.io.IOException; -import java.net.URL; - -import org.apache.fop.render.afp.exceptions.FontRuntimeException; -import org.xml.sax.EntityResolver; -import org.xml.sax.InputSource; - -/** - * An entity resolver for both DOM and SAX models of the SAX document. - * <p> - * The entity resolver only handles queries for the DTD. It will find any URI - * with a recognised public id and return an {@link org.xml.sax.InputSource}. - * <p> - * @author <a href="mailto:joe@exubero.com">Joe Schmetzer</a> - */ -public class DTDEntityResolver implements EntityResolver { - - /** Public ID for the AFP fonts 1.0 DTD. */ - public static final String AFP_DTD_1_0_ID - = "-//APACHE/DTD AFP Installed Font Definition DTD 1.0//EN"; - - /** Resource location for the AFP fonts 1.0 DTD. */ - public static final String AFP_DTD_1_0_RESOURCE - = "afp-fonts-1.0.dtd"; - - /** Public ID for the AFP fonts 1.1 DTD. */ - public static final String AFP_DTD_1_1_ID - = "-//APACHE/DTD AFP Installed Font Definition DTD 1.1//EN"; - - /** Resource location for the AFP fonts 1.1 DTD. */ - public static final String AFP_DTD_1_1_RESOURCE - = "afp-fonts-1.1.dtd"; - - /** Public ID for the AFP fonts 1.2 DTD. */ - public static final String AFP_DTD_1_2_ID - = "-//APACHE/DTD AFP Installed Font Definition DTD 1.2//EN"; - - /** Resource location for the AFP fonts 1.2 DTD. */ - public static final String AFP_DTD_1_2_RESOURCE - = "afp-fonts-1.2.dtd"; - - /** - * Resolve the combination of system and public identifiers. - * If this resolver recognises the publicId, it will handle the resolution - * from the classpath, otherwise it will return null and allow the default - * resolution to occur. - * - * @param publicId the public identifier to use - * @param systemId the system identifier to resolve - * @return An input source to the entity or null if not handled - * @throws IOException an error reading the stream - */ - public InputSource resolveEntity(String publicId, String systemId) - throws IOException { - - URL resource = null; - if ( AFP_DTD_1_2_ID.equals(publicId) ) { - resource = getResource( AFP_DTD_1_2_RESOURCE ); - } else if ( AFP_DTD_1_1_ID.equals(publicId) ) { - resource = getResource( AFP_DTD_1_1_RESOURCE ); - } else if ( AFP_DTD_1_0_ID.equals(publicId) ) { - throw new FontRuntimeException( - "The AFP Installed Font Definition 1.0 DTD is not longer supported" ); - } else if (systemId != null && systemId.indexOf("afp-fonts.dtd") >= 0 ) { - throw new FontRuntimeException( - "The AFP Installed Font Definition DTD must be specified using the public id" ); - } else { - return null; - } - - InputSource inputSource = new InputSource( resource.openStream() ); - inputSource.setPublicId( publicId ); - inputSource.setSystemId( systemId ); - - return inputSource; - } - - /** - * Returns the URL of a resource on the classpath - * @param resourceName the path to the resource relative to the root of the - * classpath. - * @return the URL of the required resource - * @throws FontRuntimeException if the resource could not be found. - */ - private URL getResource(String resourcePath) { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } - - URL resource = cl.getResource( resourcePath ); - if (resource == null) { - throw new FontRuntimeException( "Resource " + resourcePath - + "could not be found on the classpath" ); - } - - return resource; - } -} diff --git a/src/java/org/apache/fop/render/afp/tools/StringUtils.java b/src/java/org/apache/fop/render/afp/tools/StringUtils.java deleted file mode 100644 index c49509aa0..000000000 --- a/src/java/org/apache/fop/render/afp/tools/StringUtils.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.tools; - -/** - * Library of utility methods useful in dealing with strings. - * - */ -public class StringUtils { - - /** - * Padds the string to the left with the given character for - * the specified length. - * @param input The input string. - * @param padding The char used for padding. - * @param length The length of the new string. - * @return The padded string. - */ - public static String lpad(String input, char padding, int length) { - - if (input == null) { - input = new String(); - } - - if (input.length() >= length) { - return input; - } else { - StringBuffer result = new StringBuffer(); - int numChars = length - input.length(); - for (int i = 0; i < numChars; i++) { - result.append(padding); - } - result.append(input); - return result.toString(); - } - } - - /** - * Padds the string to the right with the given character for - * the specified length. - * @param input The input string. - * @param padding The char used for padding. - * @param length The length of the new string. - * @return The padded string. - */ - public static String rpad(String input, char padding, int length) { - - if (input == null) { - input = new String(); - } - - if (input.length() >= length) { - return input; - } else { - StringBuffer result = new StringBuffer(input); - int numChars = length - input.length(); - for (int i = 0; i < numChars; i++) { - result.append(padding); - } - return result.toString(); - } - } - -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/tools/StructuredFieldReader.java b/src/java/org/apache/fop/render/afp/tools/StructuredFieldReader.java deleted file mode 100644 index 48beff023..000000000 --- a/src/java/org/apache/fop/render/afp/tools/StructuredFieldReader.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* $Id$ */ - -package org.apache.fop.render.afp.tools; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A helper class to read structured fields from a MO:DCA document. Each - * component of a mixed object document is explicitly defined and delimited - * in the data. This is accomplished through the use of MO:DCA data structures, - * called structured fields. Structured fields are used to envelop document - * components and to provide commands and information to applications using - * the data. Structured fields may contain one or more parameters. Each - * parameter provides one value from a set of values defined by the architecture. - * <p/> - * MO:DCA structured fields consist of two parts: an introducer that identifies - * the length and type of the structured field, and data that provides the - * structured field's effect. The data is contained in a set of parameters, - * which can consist of other data structures and data elements. The maximum - * length of a structured field is 32767 bytes. - * <p/> - */ -public class StructuredFieldReader { - - /** - * The input stream to read - */ - private InputStream inputStream = null; - - /** - * The constructor for the StructuredFieldReader - * @param inputStream the input stream to process - */ - public StructuredFieldReader(InputStream inputStream) { - this.inputStream = inputStream; - } - - /** - * Get the next structured field as identified by the identifer - * parameter (this must be a valid MO:DCA structured field. - * @param identifier the three byte identifier - * @throws IOException if an I/O exception occurred - * @return the next structured field or null when there are no more - */ - public byte[] getNext(byte[] identifier) throws IOException { - - int bufferPointer = 0; - byte[] bufferData = new byte[identifier.length + 2]; - for (int x = 0; x < identifier.length; x++) { - bufferData[x] = 0x00; - } - - int c; - while ((c = inputStream.read()) > -1) { - - bufferData[bufferPointer] = (byte) c; - - // Check the last characters in the buffer - int index = 0; - boolean found = true; - - for (int i = identifier.length - 1; i > -1; i--) { - - int p = bufferPointer - index; - if (p < 0) { - p = bufferData.length + p; - } - - index++; - - if (identifier[i] != bufferData[p]) { - found = false; - break; - } - - } - - if (found) { - - byte[] length = new byte[2]; - - int a = bufferPointer - identifier.length; - if (a < 0) { - a = bufferData.length + a; - } - - int b = bufferPointer - identifier.length - 1; - if (b < 0) { - b = bufferData.length + b; - } - - length[0] = bufferData[b]; - length[1] = bufferData[a]; - - int reclength = ((length[0] & 0xFF) << 8) - + (length[1] & 0xFF) - identifier.length - 2; - - byte[] retval = new byte[reclength]; - - inputStream.read(retval, 0, reclength); - - return retval; - - } - - bufferPointer++; - if (bufferPointer >= bufferData.length) { - bufferPointer = 0; - } - - } - - return null; - } -} diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java index f67c2c7a2..5b4c6b13a 100644 --- a/src/java/org/apache/fop/render/awt/AWTRenderer.java +++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java @@ -149,14 +149,11 @@ public class AWTRenderer extends Java2DRenderer implements Pageable { Rectangle2D bounds = getPageViewport(pageNum).getViewArea(); pageWidth = (int) Math.round(bounds.getWidth() / 1000f); pageHeight = (int) Math.round(bounds.getHeight() / 1000f); - double scaleX = scaleFactor + double scale = scaleFactor * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION) / userAgent.getTargetPixelUnitToMillimeter(); - double scaleY = scaleFactor - * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION) - / userAgent.getTargetPixelUnitToMillimeter(); - int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5); - int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5); + int bitmapWidth = (int) ((pageWidth * scale) + 0.5); + int bitmapHeight = (int) ((pageHeight * scale) + 0.5); return new Dimension(bitmapWidth, bitmapHeight); } diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 65e6ac0fe..933398125 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java +++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java @@ -135,7 +135,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem /** The current state, holds a Graphics2D and its context */ protected Java2DGraphicsState state; - private Stack stateStack = new Stack(); + private final Stack stateStack = new Stack(); /** true if the renderer has finished rendering all the pages */ private boolean renderingDone; @@ -146,9 +146,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem public Java2DRenderer() { } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void setUserAgent(FOUserAgent foUserAgent) { super.setUserAgent(foUserAgent); userAgent.setRendererOverride(this); // for document regeneration @@ -164,9 +162,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem return userAgent; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void setupFontInfo(FontInfo inFontInfo) { //Don't call super.setupFontInfo() here! Java2D needs a special font setup // create a temp Image to test font metrics on @@ -437,16 +433,12 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem state.transform(new AffineTransform(CTMHelper.toPDFArray(ctm))); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void endVParea() { restoreGraphicsState(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected List breakOutOfStateStack() { log.debug("Block.FIXED --> break out"); List breakOutList; @@ -459,10 +451,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem return breakOutList; } - /** - * {@inheritDoc} - * java.util.List) - */ + /** {@inheritDoc} */ protected void restoreStateStackAfterBreakOut(List breakOutList) { log.debug("Block.FIXED --> restoring context after break-out"); @@ -474,16 +463,12 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void updateColor(Color col, boolean fill) { state.updateColor(col); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void clip() { if (currentPath == null) { throw new IllegalStateException("No current path available!"); @@ -492,16 +477,12 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem currentPath = null; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void closePath() { currentPath.closePath(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void lineTo(float x, float y) { if (currentPath == null) { currentPath = new GeneralPath(); @@ -509,9 +490,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem currentPath.lineTo(x, y); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void moveTo(float x, float y) { if (currentPath == null) { currentPath = new GeneralPath(); @@ -519,23 +498,17 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem currentPath.moveTo(x, y); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void clipRect(float x, float y, float width, float height) { state.updateClip(new Rectangle2D.Float(x, y, width, height)); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void fillRect(float x, float y, float width, float height) { state.getGraph().fill(new Rectangle2D.Float(x, y, width, height)); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz, boolean startOrBefore, int style, Color col) { Graphics2D g2d = state.getGraph(); @@ -706,9 +679,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem } } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void renderText(TextArea text) { renderInlineAreaBackAndBorders(text); @@ -890,18 +861,20 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem super.renderLeader(area); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public void renderImage(Image image, Rectangle2D pos) { // endTextObject(); String url = image.getURL(); drawImage(url, pos); } - /** - * {@inheritDoc} - */ + private static final ImageFlavor[] FLAVOURS = new ImageFlavor[] + {ImageFlavor.GRAPHICS2D, + ImageFlavor.BUFFERED_IMAGE, + ImageFlavor.RENDERED_IMAGE, + ImageFlavor.XML_DOM}; + + /** {@inheritDoc} */ protected void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { int x = currentIPPosition + (int)Math.round(pos.getX()); @@ -913,14 +886,9 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem try { ImageSessionContext sessionContext = getUserAgent().getImageSessionContext(); info = manager.getImageInfo(uri, sessionContext); - final ImageFlavor[] flavors = new ImageFlavor[] - {ImageFlavor.GRAPHICS2D, - ImageFlavor.BUFFERED_IMAGE, - ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM}; Map hints = ImageUtil.getDefaultHints(sessionContext); org.apache.xmlgraphics.image.loader.Image img = manager.getImage( - info, flavors, hints, sessionContext); + info, FLAVOURS, hints, sessionContext); if (img instanceof ImageGraphics2D) { ImageGraphics2D imageG2D = (ImageGraphics2D)img; int width = (int)pos.getWidth(); diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java index 12b269a44..99502096c 100644 --- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java +++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java @@ -20,6 +20,8 @@ package org.apache.fop.render.java2d; import java.awt.geom.AffineTransform; +import java.io.IOException; +import java.util.Map; import org.w3c.dom.Document; @@ -29,9 +31,11 @@ import org.apache.batik.gvt.GraphicsNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; +import org.apache.fop.render.RendererContextConstants; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; @@ -66,6 +70,11 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler pdfi.height = ((Integer)context.getProperty(HEIGHT)).intValue(); pdfi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue(); pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue(); + Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); + if (foreign != null + && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) { + pdfi.paintAsBitmap = true; + } return pdfi; } @@ -83,6 +92,7 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler public int currentXPosition; /** see Java2D_YPOS */ public int currentYPosition; + public boolean paintAsBitmap; /** {@inheritDoc} */ public String toString() { @@ -91,7 +101,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler + "width = " + width + ", " + "height = " + height + ", " + "currentXPosition = " + currentXPosition + ", " - + "currentYPosition = " + currentYPosition + "}"; + + "currentYPosition = " + currentYPosition + ", " + + "paintAsBitmap = " + paintAsBitmap + "}"; } } @@ -103,17 +114,33 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler log.debug("renderSVGDocument(" + context + ", " + doc + ", " + info + ")"); } + // fallback paint as bitmap + if (info.paintAsBitmap) { + try { + super.renderSVGDocument(context, doc); + } catch (IOException ioe) { + SVGEventProducer eventProducer = SVGEventProducer.Provider.get( + context.getUserAgent().getEventBroadcaster()); + eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc)); + } + return; + } + int x = info.currentXPosition; int y = info.currentYPosition; SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); - GVTBuilder builder = new GVTBuilder(); BridgeContext ctx = new BridgeContext(ua); + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(doc); + GraphicsNode root; try { - root = builder.build(ctx, doc); + GVTBuilder builder = new GVTBuilder(); + root = builder.build(ctx, clonedDoc); } catch (Exception e) { SVGEventProducer eventProducer = SVGEventProducer.Provider.get( context.getUserAgent().getEventBroadcaster()); @@ -126,8 +153,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler float iw = (float) ctx.getDocumentSize().getWidth() * 1000f; float ih = (float) ctx.getDocumentSize().getHeight() * 1000f; - float w = (float) info.width; - float h = (float) info.height; + float w = info.width; + float h = info.height; AffineTransform origTransform = info.state.getGraph().getTransform(); diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java index 509d4538e..b492f1b07 100644 --- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java +++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java @@ -534,7 +534,7 @@ public class PCLRenderer extends PrintRenderer implements PCLConstants { public Dimension getImageSize() { return paintRect.getSize(); } - + }; g2a.paintImage(painter, rc, paintRect.x, paintRect.y, paintRect.width, paintRect.height); diff --git a/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java b/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java index 70e0f7eb5..4b0f35bec 100644 --- a/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java +++ b/src/java/org/apache/fop/render/pdf/PDFContentGenerator.java @@ -29,8 +29,8 @@ import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFFilterList; import org.apache.fop.pdf.PDFNumber; +import org.apache.fop.pdf.PDFPaintingState; import org.apache.fop.pdf.PDFResourceContext; -import org.apache.fop.pdf.PDFState; import org.apache.fop.pdf.PDFStream; import org.apache.fop.pdf.PDFTextUtil; import org.apache.fop.pdf.PDFXObject; @@ -52,7 +52,7 @@ public class PDFContentGenerator { private PDFStream currentStream; /** drawing state */ - protected PDFState currentState = null; + protected PDFPaintingState currentState = null; /** Text generation utility holding the current font status */ protected PDFTextUtil textutil; @@ -77,7 +77,7 @@ public class PDFContentGenerator { } }; - this.currentState = new PDFState(); + this.currentState = new PDFPaintingState(); } /** @@ -116,7 +116,7 @@ public class PDFContentGenerator { * Returns the {@code PDFState} associated with this instance. * @return the PDF state */ - public PDFState getState() { + public PDFPaintingState getState() { return this.currentState; } @@ -149,7 +149,7 @@ public class PDFContentGenerator { /** {@inheritDoc} */ protected void saveGraphicsState() { endTextObject(); - currentState.push(); + currentState.save(); currentStream.add("q\n"); } @@ -162,7 +162,7 @@ public class PDFContentGenerator { endTextObject(); currentStream.add("Q\n"); if (popState) { - currentState.pop(); + currentState.restore(); } } diff --git a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java index 4da7f13cb..102c1ab45 100644 --- a/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java @@ -98,7 +98,7 @@ public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter { AffineTransform transform = new AffineTransform(); transform.translate(fx, fy); generator.getState().concatenate(transform); - graphics.setPDFState(generator.getState()); + graphics.setPaintingState(generator.getState()); graphics.setOutputStream(pdfInfo.outputStream); if (pdfInfo.paintAsBitmap) { diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java b/src/java/org/apache/fop/render/pdf/PDFImageHandler.java index f93ee5a97..934d306b9 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandler.java @@ -24,35 +24,15 @@ import java.awt.Rectangle; import java.io.IOException; import org.apache.xmlgraphics.image.loader.Image; -import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.fop.pdf.PDFXObject; +import org.apache.fop.render.ImageHandlerBase; import org.apache.fop.render.RendererContext; /** * This interface is used for handling all sorts of image type for PDF output. */ -public interface PDFImageHandler { - - /** - * Returns the priority for this image handler. A lower value means higher priority. This - * information is used to build the ordered/prioritized list of supported ImageFlavors for - * the PDF renderer. The built-in handlers use priorities between 100 and 999. - * @return a positive integer (>0) indicating the priority - */ - int getPriority(); - - /** - * Returns the {@link ImageFlavor}s supported by this instance - * @return the supported image flavors - */ - ImageFlavor[] getSupportedImageFlavors(); - - /** - * Returns the {@link Image} subclass supported by this instance. - * @return the Image type - */ - Class getSupportedImageClass(); +public interface PDFImageHandler extends ImageHandlerBase { /** * Generates the PDF objects for the given {@link Image} instance. If the handler generates diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java index 610fa274f..18717809d 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java @@ -108,7 +108,7 @@ public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D AffineTransform transform = new AffineTransform(); transform.translate(fx, fy); generator.getState().concatenate(transform); - graphics.setPDFState(generator.getState()); + graphics.setPaintingState(generator.getState()); graphics.setOutputStream(generator.getOutputStream()); Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java index b664a0a24..1d4c733a3 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java @@ -19,171 +19,18 @@ package org.apache.fop.render.pdf; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.xmlgraphics.image.loader.Image; -import org.apache.xmlgraphics.image.loader.ImageFlavor; -import org.apache.xmlgraphics.util.Service; +import org.apache.fop.render.AbstractImageHandlerRegistry; /** * This class holds references to various image handlers used by the PDF renderer. It also * supports automatic discovery of additional handlers available through * the class path. */ -public class PDFImageHandlerRegistry { - - /** the logger */ - private static Log log = LogFactory.getLog(PDFImageHandlerRegistry.class); - - private static final Comparator HANDLER_COMPARATOR = new Comparator() { - public int compare(Object o1, Object o2) { - PDFImageHandler h1 = (PDFImageHandler)o1; - PDFImageHandler h2 = (PDFImageHandler)o2; - return h1.getPriority() - h2.getPriority(); - } - }; - - /** Map containing PDF image handlers for various MIME types */ - private Map handlers = new java.util.HashMap(); - /** List containing the same handlers as above but ordered by priority */ - private List handlerList = new java.util.LinkedList(); +public class PDFImageHandlerRegistry extends AbstractImageHandlerRegistry { - /** Sorted Set of registered handlers */ - private ImageFlavor[] supportedFlavors = new ImageFlavor[0]; - private int handlerRegistrations; - private int lastSync; - - /** - * Default constructor. - */ - public PDFImageHandlerRegistry() { - discoverHandlers(); - } - - /** - * Add an PDFImageHandler. The handler itself is inspected to find out what it supports. - * @param classname the fully qualified class name - */ - public void addHandler(String classname) { - try { - PDFImageHandler handlerInstance - = (PDFImageHandler)Class.forName(classname).newInstance(); - addHandler(handlerInstance); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Could not find " - + classname); - } catch (InstantiationException e) { - throw new IllegalArgumentException("Could not instantiate " - + classname); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException("Could not access " - + classname); - } catch (ClassCastException e) { - throw new IllegalArgumentException(classname - + " is not an " - + PDFImageHandler.class.getName()); - } + /** {@inheritDoc} */ + public Class getHandlerClass() { + return PDFImageHandler.class; } - /** - * Add an image handler. The handler itself is inspected to find out what it supports. - * @param handler the PDFImageHandler instance - */ - public synchronized void addHandler(PDFImageHandler handler) { - Class imageClass = handler.getSupportedImageClass(); - this.handlers.put(imageClass, handler); - - //Sorted insert - ListIterator iter = this.handlerList.listIterator(); - while (iter.hasNext()) { - PDFImageHandler h = (PDFImageHandler)iter.next(); - if (HANDLER_COMPARATOR.compare(handler, h) < 0) { - iter.previous(); - break; - } - } - iter.add(handler); - this.handlerRegistrations++; - } - - /** - * Returns an PDFImageHandler which handles an specific image type given the MIME type - * of the image. - * @param img the Image to be handled - * @return the PDFImageHandler responsible for handling the image or null if none is available - */ - public PDFImageHandler getHandler(Image img) { - return getHandler(img.getClass()); - } - - /** - * Returns an PDFImageHandler which handles an specific image type given the MIME type - * of the image. - * @param imageClass the Image subclass for which to get a handler - * @return the PDFImageHandler responsible for handling the image or null if none is available - */ - protected synchronized PDFImageHandler getHandler(Class imageClass) { - PDFImageHandler handler = null; - Class cl = imageClass; - while (cl != null) { - handler = (PDFImageHandler)handlers.get(cl); - if (handler != null) { - break; - } - cl = cl.getSuperclass(); - } - return handler; - } - - /** - * Returns the ordered array of supported image flavors. - * @return the array of image flavors - */ - public synchronized ImageFlavor[] getSupportedFlavors() { - if (this.lastSync != this.handlerRegistrations) { - //Extract all ImageFlavors into a single array - List flavors = new java.util.ArrayList(); - Iterator iter = this.handlerList.iterator(); - while (iter.hasNext()) { - ImageFlavor[] f = ((PDFImageHandler)iter.next()).getSupportedImageFlavors(); - for (int i = 0; i < f.length; i++) { - flavors.add(f[i]); - } - } - this.supportedFlavors = (ImageFlavor[])flavors.toArray(new ImageFlavor[flavors.size()]); - this.lastSync = this.handlerRegistrations; - } - return this.supportedFlavors; - } - - /** - * Discovers PDFImageHandler implementations through the classpath and dynamically - * registers them. - */ - private void discoverHandlers() { - // add mappings from available services - Iterator providers = Service.providers(PDFImageHandler.class); - if (providers != null) { - while (providers.hasNext()) { - PDFImageHandler handler = (PDFImageHandler)providers.next(); - try { - if (log.isDebugEnabled()) { - log.debug("Dynamically adding PDFImageHandler: " - + handler.getClass().getName()); - } - addHandler(handler); - } catch (IllegalArgumentException e) { - log.error("Error while adding PDFImageHandler", e); - } - - } - } - } } diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java index 3764486b7..d1b7aa986 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java @@ -148,7 +148,7 @@ public class PDFImageHandlerSVG implements ImageHandler { generator.comment("SVG start"); //Save state and update coordinate system for the SVG image - generator.getState().push(); + generator.getState().save(); generator.getState().concatenate(imageTransform); //Now that we have the complete transformation matrix for the image, we can update the @@ -157,7 +157,7 @@ public class PDFImageHandlerSVG implements ImageHandler { SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG); aBridge.getCurrentTransform().setTransform(generator.getState().getTransform()); - graphics.setPDFState(generator.getState()); + graphics.setPaintingState(generator.getState()); graphics.setOutputStream(generator.getOutputStream()); try { root.paint(graphics); @@ -167,7 +167,7 @@ public class PDFImageHandlerSVG implements ImageHandler { context.getUserAgent().getEventBroadcaster()); eventProducer.svgRenderingError(this, e, image.getInfo().getOriginalURI()); } - generator.getState().pop(); + generator.getState().restore(); generator.restoreGraphicsState(); generator.comment("SVG end"); } diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java index d111e733f..26ba83371 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java @@ -24,14 +24,12 @@ import java.awt.Rectangle; import java.io.IOException; import java.util.Map; -import org.w3c.dom.Document; - +import org.apache.fop.pdf.PDFXObject; +import org.apache.fop.render.RendererContext; import org.apache.xmlgraphics.image.loader.Image; import org.apache.xmlgraphics.image.loader.ImageFlavor; import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; - -import org.apache.fop.pdf.PDFXObject; -import org.apache.fop.render.RendererContext; +import org.w3c.dom.Document; /** * PDFImageHandler implementation which handles XML-based images. diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 730acb540..e0e1bab69 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -82,9 +82,9 @@ import org.apache.fop.pdf.PDFLink; import org.apache.fop.pdf.PDFNumber; import org.apache.fop.pdf.PDFOutline; import org.apache.fop.pdf.PDFPage; +import org.apache.fop.pdf.PDFPaintingState; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; -import org.apache.fop.pdf.PDFState; import org.apache.fop.pdf.PDFTextUtil; import org.apache.fop.pdf.PDFXMode; import org.apache.fop.pdf.PDFXObject; @@ -92,8 +92,9 @@ import org.apache.fop.render.AbstractPathOrientedRenderer; import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.traits.RuleStyle; +import org.apache.fop.util.AbstractPaintingState; import org.apache.fop.util.CharUtilities; -import org.apache.fop.util.ColorUtil; +import org.apache.fop.util.AbstractPaintingState.AbstractData; /** * Renderer that renders areas to PDF. @@ -190,7 +191,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf protected int pageHeight; /** Image handler registry */ - private PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry(); + private final PDFImageHandlerRegistry imageHandlerRegistry = new PDFImageHandlerRegistry(); /** @@ -213,7 +214,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf return this.generator; } - PDFState getState() { + PDFPaintingState getState() { return getGenerator().getState(); } @@ -262,11 +263,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf //pvReferences.clear(); pdfResources = null; this.generator = null; - //currentStream = null; currentContext = null; currentPage = null; - //currentState = null; - //this.textutil = null; idPositions.clear(); idGoTos.clear(); @@ -505,7 +503,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf } // multiply with current CTM generator.concatenate(new AffineTransform(CTMHelper.toPDFArray(ctm))); - //currentStream.add(CTMHelper.toPDFString(ctm) + " cm\n"); } /** {@inheritDoc} */ @@ -516,11 +513,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf /** {@inheritDoc} */ protected void concatenateTransformationMatrix(AffineTransform at) { generator.concatenate(at); - /* - if (!at.isIdentity()) { - currentState.concatenate(at); - currentStream.add(CTMHelper.toPDFString(at, false) + " cm\n"); - }*/ } /** @@ -582,10 +574,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf /** * {@inheritDoc} */ - protected void fillRect(float x, float y, float w, float h) { - if (w != 0 && h != 0) { + protected void fillRect(float x, float y, float width, float height) { + if (width > 0 && height > 0) { generator.add(format(x) + " " + format(y) + " " - + format(w) + " " + format(h) + " re f\n"); + + format(width) + " " + format(height) + " re f\n"); } } @@ -607,11 +599,12 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf * @return the saved state stack to recreate later */ protected List breakOutOfStateStack() { + PDFPaintingState paintingState = getState(); List breakOutList = new java.util.ArrayList(); - PDFState.Data data; + AbstractPaintingState.AbstractData data; while (true) { - data = getState().getData(); - if (getState().pop() == null) { + data = paintingState.getData(); + if (paintingState.restore() == null) { break; } if (breakOutList.size() == 0) { @@ -629,10 +622,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf */ protected void restoreStateStackAfterBreakOut(List breakOutList) { generator.comment("------ restoring context after break-out..."); - PDFState.Data data; +// currentState.pushAll(breakOutList); + AbstractData data; Iterator i = breakOutList.iterator(); while (i.hasNext()) { - data = (PDFState.Data)i.next(); + data = (AbstractData)i.next(); saveGraphicsState(); AffineTransform at = data.getTransform(); concatenateTransformationMatrix(at); @@ -1131,7 +1125,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf info, supportedFlavors, hints, sessionContext); //First check for a dynamically registered handler - PDFImageHandler handler = imageHandlerRegistry.getHandler(img.getClass()); + PDFImageHandler handler + = (PDFImageHandler)imageHandlerRegistry.getHandler(img.getClass()); if (handler != null) { if (log.isDebugEnabled()) { log.debug("Using PDFImageHandler: " + handler.getClass().getName()); @@ -1170,6 +1165,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf this.generator.flushPDFDoc(); } catch (IOException ioe) { // ioexception will be caught later + log.error(ioe.getMessage()); } } @@ -1198,7 +1194,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer implements PDFConf x, y, width, height, foreignAttributes); context.setProperty(PDFRendererContextConstants.PDF_DOCUMENT, pdfDoc); context.setProperty(PDFRendererContextConstants.OUTPUT_STREAM, ostream); - context.setProperty(PDFRendererContextConstants.PDF_STATE, getState()); context.setProperty(PDFRendererContextConstants.PDF_PAGE, currentPage); context.setProperty(PDFRendererContextConstants.PDF_CONTEXT, currentContext == null ? currentPage : currentContext); diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java index d416f1147..fccba1c25 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java +++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java @@ -54,6 +54,7 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator /** * Default constructor + * * @param userAgent user agent */ public PDFRendererConfigurator(FOUserAgent userAgent) { @@ -64,6 +65,7 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator * Configure the PDF renderer. * Get the configuration to be used for pdf stream filters, * fonts etc. + * * @param renderer pdf renderer * @throws FOPException fop exception */ @@ -97,7 +99,8 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator if (s != null) { pdfUtil.setXMode(PDFXMode.valueOf(s)); } - Configuration encryptionParamsConfig = cfg.getChild(PDFRenderer.ENCRYPTION_PARAMS, false); + Configuration encryptionParamsConfig + = cfg.getChild(PDFRenderer.ENCRYPTION_PARAMS, false); if (encryptionParamsConfig != null) { PDFEncryptionParams encryptionParams = new PDFEncryptionParams(); Configuration ownerPasswordConfig = encryptionParamsConfig.getChild( @@ -142,8 +145,8 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator if (s != null) { pdfUtil.setOutputProfileURI(s); } - Configuration disableColorSpaceConfig - = cfg.getChild(PDFRenderer.KEY_DISABLE_SRGB_COLORSPACE, false); + Configuration disableColorSpaceConfig = cfg.getChild( + PDFRenderer.KEY_DISABLE_SRGB_COLORSPACE, false); if (disableColorSpaceConfig != null) { pdfUtil.setDisableSRGBColorSpace( disableColorSpaceConfig.getValueAsBoolean(false)); @@ -152,6 +155,7 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator /** * Builds a filter map from an Avalon Configuration object. + * * @param cfg the Configuration object * @return Map the newly built filter map * @throws ConfigurationException if a filter list is defined twice diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java index de51aabc7..11380bf59 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java +++ b/src/java/org/apache/fop/render/pdf/PDFRendererContextConstants.java @@ -29,9 +29,6 @@ public interface PDFRendererContextConstants extends RendererContextConstants { /** The PDF document that this image is being drawn into. */ String PDF_DOCUMENT = "pdfDoc"; - /** The current pdf state. */ - String PDF_STATE = "pdfState"; - /** The current PDF page for page renference and as a resource context. */ String PDF_PAGE = "pdfPage"; diff --git a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java index 11d9b1c3f..8f7aad300 100644 --- a/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java +++ b/src/java/org/apache/fop/render/pdf/PDFSVGHandler.java @@ -36,11 +36,9 @@ import org.apache.batik.util.SVGConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.xmlgraphics.util.QName; - import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFPage; import org.apache.fop.pdf.PDFResourceContext; @@ -89,9 +87,9 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler pdfi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue(); pdfi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION); Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); - QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); + if (foreign != null - && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) { + && BITMAP.equalsIgnoreCase((String)foreign.get(CONVERSION_MODE))) { pdfi.paintAsBitmap = true; } return pdfi; @@ -105,8 +103,6 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler public PDFDocument pdfDoc; /** see OUTPUT_STREAM */ public OutputStream outputStream; - /** see PDF_STATE */ - //public PDFState pdfState; /** see PDF_PAGE */ public PDFPage pdfPage; /** see PDF_CONTEXT */ @@ -167,8 +163,6 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler AffineTransform resolutionScaling = new AffineTransform(); resolutionScaling.scale(s, s); - GVTBuilder builder = new GVTBuilder(); - //Controls whether text painted by Batik is generated using text or path operations boolean strokeText = false; Configuration cfg = pdfInfo.cfg; @@ -182,10 +176,14 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler userAgent.getImageSessionContext(), new AffineTransform()); + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(doc); + GraphicsNode root; try { - root = builder.build(ctx, doc); - builder = null; + GVTBuilder builder = new GVTBuilder(); + root = builder.build(ctx, clonedDoc); } catch (Exception e) { SVGEventProducer eventProducer = SVGEventProducer.Provider.get( context.getUserAgent().getEventBroadcaster()); @@ -196,8 +194,8 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler float w = (float)ctx.getDocumentSize().getWidth() * 1000f; float h = (float)ctx.getDocumentSize().getHeight() * 1000f; - float sx = pdfInfo.width / (float)w; - float sy = pdfInfo.height / (float)h; + float sx = pdfInfo.width / w; + float sy = pdfInfo.height / h; //Scaling and translation for the bounding box of the image AffineTransform scaling = new AffineTransform( @@ -247,7 +245,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler generator.comment("SVG start"); //Save state and update coordinate system for the SVG image - generator.getState().push(); + generator.getState().save(); generator.getState().concatenate(imageTransform); //Now that we have the complete transformation matrix for the image, we can update the @@ -256,7 +254,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG); aBridge.getCurrentTransform().setTransform(generator.getState().getTransform()); - graphics.setPDFState(generator.getState()); + graphics.setPaintingState(generator.getState()); graphics.setOutputStream(pdfInfo.outputStream); try { root.paint(graphics); @@ -266,7 +264,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler context.getUserAgent().getEventBroadcaster()); eventProducer.svgRenderingError(this, e, getDocumentURI(doc)); } - generator.getState().pop(); + generator.getState().restore(); generator.restoreGraphicsState(); generator.comment("SVG end"); } diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java index e5d8200b7..542a69a4a 100644 --- a/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java @@ -33,6 +33,7 @@ import org.apache.xmlgraphics.util.QName; import org.apache.fop.fo.extensions.ExtensionElementMapping; import org.apache.fop.render.AbstractGraphics2DAdapter; +import org.apache.fop.render.Graphics2DAdapter; import org.apache.fop.render.RendererContext; import org.apache.fop.render.RendererContextConstants; import org.apache.fop.render.RendererContext.RendererContextWrapper; diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java index 1e65dfb98..7171efb4e 100644 --- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java +++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java @@ -37,6 +37,7 @@ import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.fop.fonts.FontInfo; +import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.AbstractGenericSVGHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.RendererContext; @@ -258,7 +259,6 @@ public class PSSVGHandler extends AbstractGenericSVGHandler 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) { @@ -271,9 +271,14 @@ public class PSSVGHandler extends AbstractGenericSVGHandler ctx.putBridge(tBridge); } + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(doc); + GraphicsNode root; try { - root = builder.build(ctx, doc); + GVTBuilder builder = new GVTBuilder(); + root = builder.build(ctx, clonedDoc); } catch (Exception e) { SVGEventProducer eventProducer = SVGEventProducer.Provider.get( context.getUserAgent().getEventBroadcaster()); @@ -288,7 +293,6 @@ public class PSSVGHandler extends AbstractGenericSVGHandler float sy = psInfo.getHeight() / h; ctx = null; - builder = null; try { gen.commentln("%FOPBeginSVG"); diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java index 31cb4b605..a318c6465 100644 --- a/src/java/org/apache/fop/render/ps/PSTextPainter.java +++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java @@ -19,41 +19,35 @@ package org.apache.fop.render.ps; +import java.awt.Color; import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.font.TextAttribute; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -/* java.awt.Font is not imported to avoid confusion with - org.apache.fop.fonts.Font */ - +import java.io.IOException; import java.text.AttributedCharacterIterator; import java.text.CharacterIterator; -import java.awt.font.TextAttribute; -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.xmlgraphics.java2d.TextHandler; +import java.util.List; import org.apache.batik.dom.svg.SVGOMTextElement; -import org.apache.batik.gvt.text.Mark; -import org.apache.batik.gvt.TextPainter; import org.apache.batik.gvt.TextNode; -import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; -import org.apache.batik.gvt.text.TextPaintInfo; +import org.apache.batik.gvt.TextPainter; import org.apache.batik.gvt.font.GVTFontFamily; import org.apache.batik.gvt.renderer.StrokingTextPainter; - +import org.apache.batik.gvt.text.GVTAttributedCharacterIterator; +import org.apache.batik.gvt.text.Mark; +import org.apache.batik.gvt.text.TextPaintInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; +import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; + /** * Renders the attributed character iterator of a <tt>TextNode</tt>. @@ -74,8 +68,8 @@ public class PSTextPainter implements TextPainter { /** the logger for this class */ protected Log log = LogFactory.getLog(PSTextPainter.class); - private NativeTextHandler nativeTextHandler; - private FontInfo fontInfo; + private final NativeTextHandler nativeTextHandler; + private final FontInfo fontInfo; /** * Use the stroking text painter to get the bounds and shape. @@ -317,7 +311,7 @@ public class PSTextPainter implements TextPainter { } drawPrimitiveString(g2d, loc, font, txt, tx); - loc.setLocation(loc.getX() + (double)advance, loc.getY()); + loc.setLocation(loc.getX() + advance, loc.getY()); return loc; } @@ -422,7 +416,7 @@ public class PSTextPainter implements TextPainter { fStyle |= java.awt.Font.ITALIC; } return new java.awt.Font(font.getFontName(), fStyle, - (int)(font.getFontSize() / 1000)); + (font.getFontSize() / 1000)); } private float getStringWidth(String str, Font font) { diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java index c47649eb1..eb0f4d833 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java @@ -43,7 +43,7 @@ public class PSCommentAfterElement extends AbstractPSCommentElement { * @see org.apache.fop.fo.FONode#getLocalName() */ public String getLocalName() { - return ELEMENT; + return PSCommentAfter.ELEMENT; } /** diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java index f441553b7..951e685b3 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java @@ -43,7 +43,7 @@ public class PSCommentBeforeElement extends AbstractPSCommentElement { * @see org.apache.fop.fo.FONode#getLocalName() */ public String getLocalName() { - return ELEMENT; + return PSCommentBefore.ELEMENT; } /** diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java index d1a1ede37..2044385a8 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java @@ -42,8 +42,8 @@ public class PSExtensionElementMapping extends ElementMapping { foObjs.put(PSSetupCodeElement.ELEMENT, new PSSetupCodeMaker()); foObjs.put(PSPageSetupCodeElement.ELEMENT, new PSPageSetupCodeMaker()); foObjs.put(PSSetPageDeviceElement.ELEMENT, new PSSetPageDeviceMaker()); - foObjs.put(PSCommentBeforeElement.ELEMENT, new PSCommentBeforeMaker()); - foObjs.put(PSCommentAfterElement.ELEMENT, new PSCommentAfterMaker()); + foObjs.put(PSCommentBefore.ELEMENT, new PSCommentBeforeMaker()); + foObjs.put(PSCommentAfter.ELEMENT, new PSCommentAfterMaker()); } } |