diff options
author | Adrian Cumiskey <acumiskey@apache.org> | 2008-08-27 12:35:44 +0000 |
---|---|---|
committer | Adrian Cumiskey <acumiskey@apache.org> | 2008-08-27 12:35:44 +0000 |
commit | de8752c8dc4cf502e3a98408c79f873c2964dfe5 (patch) | |
tree | 555cd4fb60d3b5df92f6cb86bc069eb16f343c31 /src/java/org/apache | |
parent | 00f21a6a4ad42bb7bafb5759d40ca69cb303fc18 (diff) | |
download | xmlgraphics-fop-de8752c8dc4cf502e3a98408c79f873c2964dfe5.tar.gz xmlgraphics-fop-de8752c8dc4cf502e3a98408c79f873c2964dfe5.zip |
* print-file level (default) resources are now immediately streamed and pages/page groups within document are written to temporary file as and when they are complete.
* Repackaged IOCA and GOCA objects.
* Image positioning still not correct and problem exists with images that are contained in an ObjectContainer. Work in progress...
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@689459 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
111 files changed, 4708 insertions, 4456 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFState.java index 241bfce3f..0f3e06070 100644 --- a/src/java/org/apache/fop/pdf/PDFState.java +++ b/src/java/org/apache/fop/pdf/PDFState.java @@ -25,6 +25,8 @@ import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.GeneralPath; +import org.apache.fop.render.AbstractState; + /** * This keeps information about the current state when writing to pdf. * It allows for creating new graphics states with the q operator. @@ -44,6 +46,8 @@ import java.awt.geom.GeneralPath; */ public class PDFState extends org.apache.fop.render.AbstractState { + private static final long serialVersionUID = 5384726143906371279L; + /** * PDF State for storing graphics state. */ @@ -58,7 +62,7 @@ public class PDFState extends org.apache.fop.render.AbstractState { * @return true if the new paint changes the current paint */ public boolean setPaint(Paint p) { - Paint paint = ((PDFData)getData()).paint; + Paint paint = ((PDFData)getData()).paint; if (paint == null) { if (p != null) { ((PDFData)getData()).paint = p; @@ -84,7 +88,7 @@ public class PDFState extends org.apache.fop.render.AbstractState { * @return true if the clip will change the current clip. */ public boolean checkClip(Shape cl) { - Shape clip = ((PDFData)getData()).clip; + Shape clip = ((PDFData)getData()).clip; if (clip == null) { if (cl != null) { return true; @@ -104,7 +108,7 @@ public class PDFState extends org.apache.fop.render.AbstractState { * @param cl the new clip in the current state */ public void setClip(Shape cl) { - Shape clip = ((PDFData)getData()).clip; + Shape clip = ((PDFData)getData()).clip; if (clip != null) { Area newClip = new Area(clip); newClip.intersect(new Area(cl)); @@ -138,9 +142,9 @@ public class PDFState extends org.apache.fop.render.AbstractState { PDFGState state; PDFGState newState = new PDFGState(); newState.addValues(defaultState); - for (Iterator iter = getStateStack().iterator(); iter.hasNext();) { - PDFData d = (PDFData)iter.next(); - state = d.gstate; + for (Iterator it = getStateStack().iterator(); it.hasNext();) { + PDFData data = (PDFData)it.next(); + state = data.gstate; if (state != null) { newState.addValues(state); } @@ -151,6 +155,16 @@ public class PDFState extends org.apache.fop.render.AbstractState { return newState; } + /** {@inheritDoc} */ + protected AbstractData instantiateData() { + return new PDFData(); + } + + /** {@inheritDoc} */ + protected AbstractState instantiateState() { + return new PDFState(); + } + private class PDFData extends org.apache.fop.render.AbstractState.AbstractData { private static final long serialVersionUID = 3527950647293177764L; @@ -164,9 +178,9 @@ public class PDFState extends org.apache.fop.render.AbstractState { private int dashOffset = 0; private Shape clip = null; private PDFGState gstate = null; - + /** {@inheritDoc} */ - public Object clone() throws CloneNotSupportedException { + public Object clone() { PDFData obj = (PDFData)super.clone(); obj.paint = this.paint; obj.backPaint = this.paint; @@ -194,9 +208,5 @@ public class PDFState extends org.apache.fop.render.AbstractState { } } - /** {@inheritDoc} */ - protected AbstractData instantiateData() { - return new PDFData(); - } } diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java index 8691e3cbe..a72c3ccb0 100644 --- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java +++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java @@ -64,7 +64,7 @@ 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 @@ -72,9 +72,6 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC 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(); //Prepare SVGUserAgent ua = new SVGUserAgent( @@ -95,6 +92,8 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC return; } + final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(context); + //Create the painter Graphics2DImagePainter painter = new Graphics2DImagePainter() { @@ -113,18 +112,21 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC public Dimension getImageSize() { return new Dimension(wrappedContext.getWidth(), wrappedContext.getHeight()); } - + }; //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()); + wrappedContext.getCurrentXPosition(), + wrappedContext.getCurrentYPosition(), + wrappedContext.getWidth(), + wrappedContext.getHeight()); } /** * Gets the document URI from a Document instance if possible. - * + * * @param doc the Document * @return the URI or null */ @@ -140,7 +142,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/AbstractState.java b/src/java/org/apache/fop/render/AbstractState.java index ee3ebd3a7..51f831011 100644 --- a/src/java/org/apache/fop/render/AbstractState.java +++ b/src/java/org/apache/fop/render/AbstractState.java @@ -5,9 +5,9 @@ * 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. @@ -29,24 +29,31 @@ import java.util.Stack; /** * A base class which holds information about the current rendering state. */ -public abstract class AbstractState { - +public abstract class AbstractState implements Cloneable, Serializable { + /** current state data */ private AbstractData currentData = null; - + /** the state stack */ - private Stack/*<AbstractData>*/ stateStack = null; + private StateStack stateStack = null; /** * Instantiates a new state data object - * + * * @return a new state data object */ protected abstract AbstractData instantiateData(); - + + /** + * Instantiates a new state object + * + * @return a new state object + */ + protected abstract AbstractState instantiateState(); + /** * Returns the currently valid state - * + * * @return the currently valid state */ public AbstractData getData() { @@ -73,7 +80,7 @@ public abstract class AbstractState { /** * Get the color. - * + * * @return the color */ public Color getColor() { @@ -85,7 +92,7 @@ public abstract class AbstractState { /** * Get the background color. - * + * * @return the background color */ public Color getBackColor() { @@ -112,7 +119,7 @@ public abstract class AbstractState { /** * Set the current font name - * + * * @param internalFontName the internal font name * @return true if the font name has changed */ @@ -126,16 +133,16 @@ public abstract class AbstractState { /** * Gets the current font name - * + * * @return the current font name */ public String getFontName() { return getData().fontName; } - + /** * Gets the current font size - * + * * @return the current font size */ public int getFontSize() { @@ -159,7 +166,7 @@ public abstract class AbstractState { /** * Set the current line width. - * + * * @param width the line width in points * @return true if the line width has changed */ @@ -173,7 +180,7 @@ public abstract class AbstractState { /** * Returns the current line width - * + * * @return the current line width */ public float getLineWidth() { @@ -182,7 +189,7 @@ public abstract class AbstractState { /** * Sets the dash array (line type) for the current basic stroke - * + * * @param dash the line dash array * @return true if the dash array has changed */ @@ -240,10 +247,10 @@ public abstract class AbstractState { return (AffineTransform) baseData.getTransform().clone(); } } - + /** * Concatenates the given AffineTransform to the current one. - * + * * @param tf the transform to concatenate to the current level transform */ public void concatenate(AffineTransform tf) { @@ -263,20 +270,15 @@ public abstract class AbstractState { * so that the state is known when popped. */ public void push() { - AbstractData copy; - try { - copy = (AbstractData)getData().clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e.getMessage()); - } + AbstractData copy = (AbstractData)getData().clone(); getStateStack().push(copy); } - + /** * Pop the state from the stack and set current values to popped state. * This should be called when a Q operator is used so * the state is restored to the correct values. - * + * * @return the restored state, null if the stack is empty */ public AbstractData pop() { @@ -290,7 +292,7 @@ public abstract class AbstractState { /** * Clears the state stack - */ + */ public void clear() { getStateStack().clear(); currentData = null; @@ -298,24 +300,32 @@ public abstract class AbstractState { /** * Return the state stack - * + * * @return the state stack */ protected Stack/*<AbstractData>*/ getStateStack() { if (stateStack == null) { - stateStack = new java.util.Stack/*<AbstractData>*/(); + stateStack = new StateStack(); } return stateStack; } /** {@inheritDoc} */ + public Object clone() { + AbstractState state = instantiateState(); + state.stateStack = new StateStack(this.stateStack); + state.currentData = (AbstractData)this.currentData.clone(); + return state; + } + + /** {@inheritDoc} */ public String toString() { - return "stateStack=" + stateStack + return ", stateStack=" + stateStack + ", currentData=" + currentData; } /** - * A base state data holding object + * A base state data holding object */ public abstract class AbstractData implements Cloneable, Serializable { @@ -345,7 +355,7 @@ public abstract class AbstractState { * a new viewport. Note that all concatenation operations are logged * so they can be replayed if necessary (ex. for block-containers with * "fixed" positioning. - * + * * @param at Transformation to perform */ public void concatenate(AffineTransform at) { @@ -354,7 +364,7 @@ public abstract class AbstractState { /** * Get the current AffineTransform. - * + * * @return the current transform */ public AffineTransform getTransform() { @@ -368,22 +378,23 @@ public abstract class AbstractState { * Resets the current AffineTransform. */ public void resetTransform() { - transform = new AffineTransform(); + transform = getBaseTransform(); +// transform = new AffineTransform(); } /** {@inheritDoc} */ - public Object clone() throws CloneNotSupportedException { - AbstractData obj = instantiateData(); - obj.color = this.color; - obj.backColor = this.backColor; - obj.fontName = this.fontName; - obj.fontSize = this.fontSize; - obj.lineWidth = this.lineWidth; - obj.dashArray = this.dashArray; - obj.transform = new AffineTransform(this.transform); - return obj; + public Object clone() { + AbstractData data = instantiateData(); + data.color = this.color; + data.backColor = this.backColor; + data.fontName = this.fontName; + data.fontSize = this.fontSize; + data.lineWidth = this.lineWidth; + data.dashArray = this.dashArray; + data.transform = new AffineTransform(this.transform); + return data; } - + /** {@inheritDoc} */ public String toString() { return "color=" + color diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java index 08ca76957..e4e234cd2 100644 --- a/src/java/org/apache/fop/render/RendererContext.java +++ b/src/java/org/apache/fop/render/RendererContext.java @@ -32,10 +32,10 @@ import org.apache.fop.apps.FOUserAgent; */ public class RendererContext { - private String mime; - private AbstractRenderer renderer; + private final String mime; + private final AbstractRenderer renderer; private FOUserAgent userAgent; - private Map props = new java.util.HashMap(); + private final Map props = new java.util.HashMap(); /** * Contructor for this class. It takes a MIME type as parameter. @@ -159,6 +159,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/goca/GraphicsImageEnd.java b/src/java/org/apache/fop/render/StateStack.java index 24c272445..ab68a3968 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsImageEnd.java +++ b/src/java/org/apache/fop/render/StateStack.java @@ -17,36 +17,34 @@ /* $Id: $ */ -package org.apache.fop.render.afp.goca; +package org.apache.fop.render; -import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject; +import java.util.Collection; /** - * A GOCA graphics image data + * No copy constructor for java.util.Stack so extended and implemented one. */ -public class GraphicsImageEnd extends AbstractPreparedAFPObject { - +public class StateStack extends java.util.Stack { + + private static final long serialVersionUID = 4897178211223823041L; + /** * Default constructor */ - public GraphicsImageEnd() { - prepareData(); + public StateStack() { + super(); } /** - * {@inheritDoc} - */ - protected void prepareData() { - super.data = new byte[] { - (byte) 0x93, // GEIMG order code - 0x00 // LENGTH - }; - } - - /** - * {@inheritDoc} + * Copy constructor + * + * @param c initial contents of stack */ - public String toString() { - return "GraphicsImageEnd"; + public StateStack(Collection c) { + elementCount = c.size(); + // 10% for growth + elementData = new Object[ + (int)Math.min((elementCount * 110L) / 100, Integer.MAX_VALUE)]; + c.toArray(elementData); } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/AFPBorderPainter.java b/src/java/org/apache/fop/render/afp/AFPBorderPainter.java new file mode 100644 index 000000000..db2b8681b --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPBorderPainter.java @@ -0,0 +1,228 @@ +/* + * 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.Color; +import java.awt.geom.AffineTransform; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.Constants; +import org.apache.fop.render.afp.modca.DataStream; +import org.apache.fop.util.ColorUtil; + +/** + * Handles the drawing of borders/lines in AFP + */ +public class AFPBorderPainter { + /** Static logging instance */ + protected static Log log = LogFactory.getLog("org.apache.fop.render.afp"); + + private static final int X1 = 0; + private static final int Y1 = 1; + private static final int X2 = 2; + private static final int Y2 = 3; + + private final AFPUnitConverter unitConv; + private final DataStream dataStream; + private final AFPState state; + + /** + * Main constructor + * + * @param state the unit converter + * @param dataStream the afp datastream + */ + public AFPBorderPainter(AFPState state, DataStream dataStream) { + this.state = state; + this.unitConv = state.getUnitConverter(); + this.dataStream = dataStream; + } + + /** {@inheritDoc} */ + public void fillRect(float x, float y, float width, float height) { + AffineTransform at = state.getData().getTransform(); + float transX = (float)at.getTranslateX(); + float transY = (float)at.getTranslateY(); + int x1 = Math.round(transX + unitConv.pt2units(x)); + int y1 = Math.round(transY + unitConv.pt2units(y)); + int x2 = Math.round(transX + unitConv.pt2units(x) + unitConv.pt2units(width)); + LineDataInfo lineDataInfo = new LineDataInfo(); + lineDataInfo.x1 = x1; + lineDataInfo.y1 = y1; + lineDataInfo.x2 = x2; + lineDataInfo.y2 = y1; + lineDataInfo.thickness = Math.round(unitConv.pt2units(height)); + lineDataInfo.color = state.getColor(); + dataStream.createLine(lineDataInfo); + } + + /** {@inheritDoc} */ + public void drawBorderLine(float x1, float y1, float x2, float y2, + boolean horz, boolean startOrBefore, int style, Color col) { + float[] srcPts = new float[] {x1 * 1000, y1 * 1000, x2 * 1000, y2 * 1000}; + float[] dstPts = new float[srcPts.length]; + int[] coords = unitConv.mpts2units(srcPts, dstPts); + + float width = dstPts[X2] - dstPts[X1]; + float height = dstPts[Y2] - dstPts[Y1]; + if ((width < 0) || (height < 0)) { + log.error("Negative extent received. Border won't be painted."); + return; + } + + LineDataInfo lineDataInfo = new LineDataInfo(); + lineDataInfo.color = col; + + switch (style) { + case Constants.EN_DOUBLE: + lineDataInfo.x1 = coords[X1]; + lineDataInfo.y1 = coords[Y1]; + if (horz) { + float h3 = height / 3; + lineDataInfo.thickness = Math.round(h3); + lineDataInfo.x2 = coords[X2]; + lineDataInfo.y2 = coords[Y1]; + dataStream.createLine(lineDataInfo); + int ym2 = Math.round(dstPts[Y1] + h3 + h3); + lineDataInfo.y1 = ym2; + lineDataInfo.y2 = ym2; + dataStream.createLine(lineDataInfo); + } else { + float w3 = width / 3; + lineDataInfo.thickness = Math.round(w3); + lineDataInfo.x2 = coords[X1]; + lineDataInfo.y2 = coords[Y2]; + dataStream.createLine(lineDataInfo); + int xm2 = Math.round(dstPts[X1] + w3 + w3); + lineDataInfo.x1 = xm2; + lineDataInfo.x2 = xm2; + dataStream.createLine(lineDataInfo); + } + break; + + case Constants.EN_DASHED: + lineDataInfo.x1 = coords[X1]; + if (horz) { + float w2 = 2 * height; + lineDataInfo.y1 = coords[Y1]; + lineDataInfo.x2 = coords[X1] + Math.round(w2); + lineDataInfo.y2 = coords[Y1]; + lineDataInfo.thickness = Math.round(height); + while (lineDataInfo.x1 + w2 < coords[X2]) { + dataStream.createLine(lineDataInfo); + lineDataInfo.x1 += 2 * w2; + } + } else { + float h2 = 2 * width; + lineDataInfo.y1 = coords[Y2]; + lineDataInfo.x2 = coords[X1]; + lineDataInfo.y2 = coords[Y1] + Math.round(h2); + lineDataInfo.thickness = Math.round(width); + while (lineDataInfo.y2 < coords[Y2]) { + dataStream.createLine(lineDataInfo); + lineDataInfo.y2 += 2 * h2; + } + } + break; + + case Constants.EN_DOTTED: + lineDataInfo.x1 = coords[X1]; + lineDataInfo.y1 = coords[Y1]; + if (horz) { + lineDataInfo.thickness = Math.round(height); + lineDataInfo.x2 = coords[X1] + lineDataInfo.thickness; + lineDataInfo.y2 = coords[Y1]; + while (lineDataInfo.x2 < coords[X2]) { + dataStream.createLine(lineDataInfo); + coords[X1] += 2 * height; + lineDataInfo.x1 = coords[X1]; + lineDataInfo.x2 = coords[X1] + lineDataInfo.thickness; + } + } else { + lineDataInfo.thickness = Math.round(width); + lineDataInfo.x2 = coords[X1]; + lineDataInfo.y2 = coords[Y1] + lineDataInfo.thickness; + while (lineDataInfo.y2 < coords[Y2]) { + dataStream.createLine(lineDataInfo); + coords[Y1] += 2 * width; + lineDataInfo.y1 = coords[Y1]; + lineDataInfo.y2 = coords[Y1] + lineDataInfo.thickness; + } + } + break; + case Constants.EN_GROOVE: + case Constants.EN_RIDGE: + float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f); + if (horz) { + lineDataInfo.x1 = coords[X1]; + lineDataInfo.x2 = coords[X2]; + float h3 = height / 3; + lineDataInfo.color = ColorUtil.lightenColor(col, -colFactor); + lineDataInfo.thickness = Math.round(h3); + lineDataInfo.y1 = lineDataInfo.y2 = coords[Y1]; + dataStream.createLine(lineDataInfo); + lineDataInfo.color = col; + lineDataInfo.y1 = lineDataInfo.y2 = Math.round(dstPts[Y1] + h3); + dataStream.createLine(lineDataInfo); + lineDataInfo.color = ColorUtil.lightenColor(col, colFactor); + lineDataInfo.y1 = lineDataInfo.y2 = Math.round(dstPts[Y1] + h3 + h3); + dataStream.createLine(lineDataInfo); + } else { + lineDataInfo.y1 = coords[Y1]; + lineDataInfo.y2 = coords[Y2]; + float w3 = width / 3; + float xm1 = dstPts[X1] + (w3 / 2); + lineDataInfo.color = ColorUtil.lightenColor(col, -colFactor); + lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1); + dataStream.createLine(lineDataInfo); + lineDataInfo.color = col; + lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1 + w3); + dataStream.createLine(lineDataInfo); + lineDataInfo.color = ColorUtil.lightenColor(col, colFactor); + lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1 + w3 + w3); + dataStream.createLine(lineDataInfo); + } + break; + + case Constants.EN_HIDDEN: + break; + + case Constants.EN_INSET: + case Constants.EN_OUTSET: + default: + lineDataInfo.x1 = coords[X1]; + lineDataInfo.y1 = coords[Y1]; + if (horz) { + lineDataInfo.thickness = Math.round(height); + lineDataInfo.x2 = coords[X2]; + lineDataInfo.y2 = coords[Y1]; + } else { + lineDataInfo.thickness = Math.round(width); + lineDataInfo.x2 = coords[X1]; + lineDataInfo.y2 = coords[Y2]; + } + lineDataInfo.x2 = (horz ? coords[X2] : coords[X1]); + lineDataInfo.y2 = (horz ? coords[Y1] : coords[Y2]); + dataStream.createLine(lineDataInfo); + } + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectFactory.java b/src/java/org/apache/fop/render/afp/AFPDataObjectFactory.java new file mode 100644 index 000000000..401d2d486 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPDataObjectFactory.java @@ -0,0 +1,211 @@ +/* + * 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.ioca.ImageContent; +import org.apache.fop.render.afp.modca.AbstractDataObject; +import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; +import org.apache.fop.render.afp.modca.Document; +import org.apache.fop.render.afp.modca.Factory; +import org.apache.fop.render.afp.modca.GraphicsObject; +import org.apache.fop.render.afp.modca.ImageObject; +import org.apache.fop.render.afp.modca.IncludeObject; +import org.apache.fop.render.afp.modca.ObjectContainer; +import org.apache.fop.render.afp.modca.Overlay; +import org.apache.fop.render.afp.modca.PageSegment; +import org.apache.fop.render.afp.modca.Registry; +import org.apache.fop.render.afp.modca.ResourceObject; +import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet; +import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; + +/** + * Factory for high level data objects (Image/Graphics etc) + */ +public class AFPDataObjectFactory { + + private final Factory factory; + + /** + * Main constructor + * + * @param factory an object factory + */ + public AFPDataObjectFactory(Factory factory) { + this.factory = factory; + } + + /** + * Creates an IOCA ImageObject or an ObjectContainer as appropriate. + * + * @param imageObjectInfo the image object info + * @return a newly created image object + */ + public AbstractDataObject createImage(AFPImageObjectInfo imageObjectInfo) { + AbstractDataObject dataObj; + Registry.ObjectType objectType = imageObjectInfo.getObjectType(); + + // A known object type so place in container + if (objectType != null) { + ObjectContainer objectContainer = factory.createObjectContainer(); + + objectContainer.setObjectClassification( + ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, + objectType); + + objectContainer.setData(imageObjectInfo.getData()); + + dataObj = objectContainer; + } else { + ImageObject imageObj = factory.createImageObject(); + if (imageObjectInfo.hasCompression()) { + int compression = imageObjectInfo.getCompression(); + switch (compression) { + case TIFFImage.COMP_FAX_G3_1D: + imageObj.setEncoding(ImageContent.COMPID_G3_MH); + break; + case TIFFImage.COMP_FAX_G3_2D: + imageObj.setEncoding(ImageContent.COMPID_G3_MR); + break; + case TIFFImage.COMP_FAX_G4_2D: + imageObj.setEncoding(ImageContent.COMPID_G3_MMR); + break; + default: + throw new IllegalStateException( + "Invalid compression scheme: " + compression); + } + } + +// imageObjectInfo.getDataWidth(), imageObjectInfo.getDataHeight(), +// objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes()); + + if (imageObjectInfo.isBuffered()) { + if (imageObjectInfo.isColor()) { + imageObj.setIDESize((byte) 24); + } else { + imageObj.setIDESize((byte) imageObjectInfo.getBitsPerPixel()); + } + imageObj.setData(imageObjectInfo.getData()); + } + dataObj = imageObj; + } + return dataObj; + } + + /** + * Creates and returns a new graphics object. + * + * @param graphicsObjectInfo the graphics object info + * @return a new graphics object + */ + public GraphicsObject createGraphic(AFPGraphicsObjectInfo graphicsObjectInfo) { + // paint the graphic using batik + GraphicsObject graphicsObj = factory.createGraphic(); + graphicsObjectInfo.getPainter().paint(graphicsObj); + return graphicsObj; + } + + /** + * Creates and returns a new include object. + * + * @param name the name of this include object + * @param dataObjectInfo a data object info + * + * @return a new include object + */ + public IncludeObject createInclude(String name, AFPDataObjectInfo dataObjectInfo) { + IncludeObject includeObj = factory.createInclude(name); + + if (dataObjectInfo instanceof AFPImageObjectInfo) { + includeObj.setObjectType(IncludeObject.TYPE_IMAGE); + } else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) { + includeObj.setObjectType(IncludeObject.TYPE_GRAPHIC); + } else { + includeObj.setObjectType(IncludeObject.TYPE_OTHER); + } + + Registry.ObjectType objectType = dataObjectInfo.getObjectType(); + if (objectType != null) { + includeObj.setObjectClassification( + ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT, + objectType); + } + + AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); + + includeObj.setObjectArea(objectAreaInfo.getX(), objectAreaInfo.getY()); + + includeObj.setObjectAreaSize( + objectAreaInfo.getWidth(), objectAreaInfo.getHeight()); + + includeObj.setOrientation(objectAreaInfo.getRotation()); + + includeObj.setMeasurementUnits( + objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes()); + +// includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT); + + return includeObj; + } + + /** + * Creates a resource object wrapper for named includable data objects + * + * @param dataObj an named object + * @param resourceInfo resource information + * @param objectType the object type + * @return a new resource object wrapper + */ + public ResourceObject createResource(AbstractNamedAFPObject dataObj, + AFPResourceInfo resourceInfo, Registry.ObjectType objectType) { + ResourceObject resourceObj = null; + String resourceName = resourceInfo.getName(); + if (resourceName != null) { + resourceObj = factory.createResource(resourceName); + } else { + resourceObj = factory.createResource(); + } + if (dataObj instanceof ObjectContainer) { + resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER); + + // mandatory triplet for object container + resourceObj.setObjectClassification( + ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, + objectType); + + } else if (dataObj instanceof ImageObject) { + resourceObj.setType(ResourceObject.TYPE_IMAGE); + } else if (dataObj instanceof GraphicsObject) { + resourceObj.setType(ResourceObject.TYPE_GRAPHIC); + } else if (dataObj instanceof Document) { + resourceObj.setType(ResourceObject.TYPE_DOCUMENT); + } else if (dataObj instanceof PageSegment) { + resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT); + } else if (dataObj instanceof Overlay) { + resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT); + } else { + throw new UnsupportedOperationException( + "Unsupported resource object type " + dataObj); + } + + resourceObj.setDataObject(dataObj); + return resourceObj; + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectInfo.java b/src/java/org/apache/fop/render/afp/AFPDataObjectInfo.java new file mode 100644 index 000000000..206c5b332 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPDataObjectInfo.java @@ -0,0 +1,143 @@ +/* + * 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.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.afp.modca.Registry; + +/** + * A list of parameters associated with an AFP data objects + */ +public abstract class AFPDataObjectInfo { + private static final Log log = LogFactory.getLog("org.apache.fop.afp"); + + /** the object area info */ + private AFPObjectAreaInfo objectAreaInfo; + + /** resource info */ + private AFPResourceInfo resourceInfo; + + private byte[] data; + + /** + * Default constructor + */ + public AFPDataObjectInfo() { + } + + /** + * Returns the resource level at which this data object should reside + * + * @return the resource level at which this data object should reside + */ + public AFPResourceInfo getResourceInfo() { + if (resourceInfo == null) { + this.resourceInfo = new AFPResourceInfo(); + } + return resourceInfo; + } + + /** + * Sets the resource level at which this object should reside + * + * @param resourceInfo the resource level at which this data object should reside + */ + public void setResourceInfo(AFPResourceInfo resourceInfo) { + this.resourceInfo = resourceInfo; + } + + /** + * Sets the object area info + * + * @param objectAreaInfo the object area info + */ + public void setObjectAreaInfo(AFPObjectAreaInfo objectAreaInfo) { + this.objectAreaInfo = objectAreaInfo; + } + + /** + * Returns the object area info + * + * @return the object area info + */ + public AFPObjectAreaInfo getObjectAreaInfo() { + return this.objectAreaInfo; + } + + /** {@inheritDoc} */ + public String toString() { + return "mimeType=" + getMimeType() + + (objectAreaInfo != null ? ", objectAreaInfo=" + objectAreaInfo : "") + + (resourceInfo != null ? ", resourceInfo=" + resourceInfo : ""); + } + + /** + * Returns the uri of this data object + * + * @return the uri of this data object + */ + public String getUri() { + return getResourceInfo().getUri(); + } + + /** + * Sets the data object uri + * + * @param uri the data object uri + */ + public void setUri(String uri) { + getResourceInfo().setUri(uri); + } + + /** + * Sets the object data + * + * @param data a data byte array + */ + public void setData(byte[] data) { + this.data = data; + } + + /** + * Returns the object data + * + * @return the object data as byte array + */ + public byte[] getData() { + return this.data; + } + + /** + * Returns the mime type of this data object + * + * @return the mime type of this data object + */ + public abstract String getMimeType(); + + /** + * Convenience method to return the object type + * + * @return the object type + */ + public Registry.ObjectType getObjectType() { + return Registry.getInstance().getObjectType(getMimeType()); + } +} 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..4d5d4c1db --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java @@ -0,0 +1,126 @@ +/* + * 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.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.fop.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/AFPGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPGraphics2D.java index 517eb8dc1..3d237c402 100644 --- a/src/java/org/apache/fop/render/afp/AFPGraphics2D.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphics2D.java @@ -5,9 +5,9 @@ * 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. @@ -19,13 +19,16 @@ package org.apache.fop.render.afp; +import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.Image; +import java.awt.Rectangle; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; @@ -34,32 +37,39 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.PathIterator; import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.io.IOException; import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.render.afp.goca.GraphicsSetLineType; import org.apache.fop.render.afp.modca.GraphicsObject; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageSize; +import org.apache.xmlgraphics.image.loader.impl.ImageRendered; import org.apache.xmlgraphics.java2d.AbstractGraphics2D; import org.apache.xmlgraphics.java2d.GraphicContext; import org.apache.xmlgraphics.java2d.StrokingTextHandler; import org.apache.xmlgraphics.java2d.TextHandler; +import org.apache.xmlgraphics.ps.ImageEncodingHelper; /** * This is a concrete implementation of <tt>AbstractGraphics2D</tt> (and * therefore of <tt>Graphics2D</tt>) which is able to generate GOCA byte * codes. - * + * * @see org.apache.xmlgraphics.java2d.AbstractGraphics2D */ public class AFPGraphics2D extends AbstractGraphics2D { private static final Log log = LogFactory.getLog(AFPGraphics2D.class); + /** graphics object */ private GraphicsObject graphicsObj = null; /** Fallback text handler */ @@ -69,62 +79,63 @@ public class AFPGraphics2D extends AbstractGraphics2D { protected TextHandler customTextHandler = null; /** AFP info */ - private AFPInfo afpInfo = null; + private AFPInfo info = null; /** Current AFP state */ - private AFPState afpState = null; + private AFPState state = null; -// /** The SVG document URI */ -// private String documentURI = null; + private AFPUnitConverter unitConv; /** + * Main constructor + * * @param textAsShapes * if true, all text is turned into shapes in the convertion. No * text is output. - * + * */ public AFPGraphics2D(boolean textAsShapes) { super(textAsShapes); } /** - * Creates a new AFPGraphics2D from an existing instance. - * - * @param g - * the AFPGraphics2D whose properties should be copied + * Copy Constructor + * + * @param g2d + * a AFPGraphics2D whose properties should be copied */ - public AFPGraphics2D(AFPGraphics2D g) { - super(g); - this.graphicsObj = g.graphicsObj; - this.fallbackTextHandler = g.fallbackTextHandler; - this.customTextHandler = g.customTextHandler; - this.afpInfo = g.afpInfo; - this.afpState = g.afpState; + public AFPGraphics2D(AFPGraphics2D g2d) { + super(g2d); + this.graphicsObj = g2d.graphicsObj; + this.fallbackTextHandler = g2d.fallbackTextHandler; + this.customTextHandler = g2d.customTextHandler; + this.info = g2d.info; + this.state = g2d.state; } /** * Sets the AFPInfo - * - * @param info - * the AFP Info to use + * + * @param afpInfo the AFP Info to use */ - public void setAFPInfo(AFPInfo info) { - this.afpInfo = info; - this.afpState = info.getState(); + public void setAFPInfo(AFPInfo afpInfo) { + this.info = afpInfo; + this.state = info.getState(); + this.unitConv = state.getUnitConverter(); } /** * Gets the AFPInfo - * + * * @return the AFPInfo */ public AFPInfo getAFPInfo() { - return this.afpInfo; + return this.info; } /** * Sets the GraphicContext - * + * * @param gc * GraphicContext to use */ @@ -143,15 +154,15 @@ public class AFPGraphics2D extends AbstractGraphics2D { if (stroke instanceof BasicStroke) { BasicStroke basicStroke = (BasicStroke) stroke; float lineWidth = basicStroke.getLineWidth(); - if (afpState.setLineWidth(lineWidth)) { + if (state.setLineWidth(lineWidth)) { getGraphicsObject().setLineWidth(Math.round(lineWidth * 2)); } // note: this is an approximation at best! float[] dashArray = basicStroke.getDashArray(); - if (afpState.setDashArray(dashArray)) { + if (state.setDashArray(dashArray)) { byte type = GraphicsSetLineType.DEFAULT; // normally SOLID if (dashArray != null) { - type = GraphicsSetLineType.DOTTED; // default to DOTTED + type = GraphicsSetLineType.DOTTED; // default to plain DOTTED if dashed line // float offset = basicStroke.getDashPhase(); if (dashArray.length == 2) { if (dashArray[0] < dashArray[1]) { @@ -181,10 +192,10 @@ public class AFPGraphics2D extends AbstractGraphics2D { log.warn("Unsupported Stroke: " + stroke.getClass().getName()); } } - + /** * Handle the Batik drawing event - * + * * @param shape * the shape to draw * @param fill @@ -196,10 +207,10 @@ public class AFPGraphics2D extends AbstractGraphics2D { graphicsObj.newSegment(); } Color col = getColor(); - if (afpState.setColor(col)) { + if (state.setColor(col)) { graphicsObj.setColor(col); } - + applyStroke(getStroke()); if (fill) { @@ -218,24 +229,19 @@ public class AFPGraphics2D extends AbstractGraphics2D { // coordinates int type = iter.currentSegment(vals); if (type == PathIterator.SEG_MOVETO) { -// log.debug("SEG_MOVETO"); openingCoords[0] = currCoords[0] = (int)Math.round(vals[0]); openingCoords[1] = currCoords[1] = (int)Math.round(vals[1]); } else { int numCoords; if (type == PathIterator.SEG_LINETO) { -// log.debug("SEG_LINETO"); numCoords = 2; } else if (type == PathIterator.SEG_QUADTO) { -// log.debug("SEG_QUADTO"); numCoords = 4; } else if (type == PathIterator.SEG_CUBICTO) { -// log.debug("SEG_CUBICTO"); numCoords = 6; } else { // close of the graphics segment if (type == PathIterator.SEG_CLOSE) { -// log.debug("SEG_CLOSE"); coords = new int[] { coords[coords.length - 2], coords[coords.length - 1], @@ -271,27 +277,27 @@ public class AFPGraphics2D extends AbstractGraphics2D { } else if (shape instanceof Line2D) { iter.currentSegment(vals); coords = new int[4]; - coords[0] = (int) Math.round(vals[0]); - coords[1] = (int) Math.round(vals[1]); + coords[0] = (int) Math.round(vals[0]); //x1 + coords[1] = (int) Math.round(vals[1]); //y1 iter.next(); iter.currentSegment(vals); - coords[2] = (int) Math.round(vals[0]); - coords[3] = (int) Math.round(vals[1]); + coords[2] = (int) Math.round(vals[0]); //x2 + coords[3] = (int) Math.round(vals[1]); //y2 graphicsObj.addLine(coords); } else if (shape instanceof Rectangle2D) { iter.currentSegment(vals); coords = new int[4]; - coords[2] = (int) Math.round(vals[0]); - coords[3] = (int) Math.round(vals[1]); + coords[2] = (int) Math.round(vals[0]); //x1 + coords[3] = (int) Math.round(vals[1]); //y1 iter.next(); iter.next(); iter.currentSegment(vals); - coords[0] = (int) Math.round(vals[0]); - coords[1] = (int) Math.round(vals[1]); + coords[0] = (int) Math.round(vals[0]); //x2 + coords[1] = (int) Math.round(vals[1]); //y2 graphicsObj.addBox(coords); } else if (shape instanceof Ellipse2D) { Ellipse2D elip = (Ellipse2D) shape; - final double factor = afpInfo.getResolution() / 100f; + final double factor = info.getResolution() / 100f; graphicsObj.setArcParams( (int)Math.round(elip.getWidth() * factor), (int)Math.round(elip.getHeight() * factor), @@ -331,7 +337,7 @@ public class AFPGraphics2D extends AbstractGraphics2D { /** * Central handler for IOExceptions for this class. - * + * * @param ioe * IOException to handle */ @@ -378,43 +384,102 @@ public class AFPGraphics2D extends AbstractGraphics2D { public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer); } - -// private BufferedImage buildBufferedImage(Dimension size) { -// return new BufferedImage(size.width, size.height, -// BufferedImage.TYPE_INT_ARGB); -// } + + private BufferedImage buildBufferedImage(Dimension size) { + return new BufferedImage(size.width, size.height, + BufferedImage.TYPE_INT_ARGB); + } + + private static final int X = 0; + + private static final int Y = 1; /** {@inheritDoc} */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { - log.debug("drawImage(): NYI img=" + img + ", x=" + x + ", y=" + y - + ", width=" + width + ", height=" + height + ", obs=" + observer); - return false; -// Dimension size = new Dimension(width, height); -// BufferedImage buf = buildBufferedImage(size); -// -// java.awt.Graphics2D graphics2D = buf.createGraphics(); -// graphics2D.setComposite(AlphaComposite.SrcOver); -// graphics2D.setBackground(new Color(1, 1, 1, 0)); -// graphics2D.setPaint(new Color(1, 1, 1, 0)); -// graphics2D.fillRect(0, 0, width, height); -// graphics2D.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); -// graphics2D.setComposite(gc.getComposite()); -// -// if (!graphics2D.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) { -// return false; -// } -// -// ImageInfo info = new ImageInfo(null, "image/unknown"); -// -// ImageSize bufsize = new ImageSize(buf.getWidth(), buf.getHeight(), 72); -// info.setSize(bufsize); -// ImageRendered imgRend = new ImageRendered(info, buf, null); -// -// AFPDataStream afpDataStream = afpInfo.getAFPDataStream(); -// ImageObjectInfo imageObjectInfo = new ImageObjectInfo(); -// afpDataStream.createObject(imageObjectInfo); -// return true; + + // draw with AWT Graphics2D + int w = Math.round(unitConv.pt2units(width)); + int h = Math.round(unitConv.pt2units(height)); + Dimension size = new Dimension(w, h); + BufferedImage buf = buildBufferedImage(size); + + java.awt.Graphics2D g = buf.createGraphics(); + g.setComposite(AlphaComposite.SrcOver); + g.setBackground(new Color(1, 1, 1, 0)); + g.setPaint(new Color(1, 1, 1, 0)); + g.fillRect(0, 0, w, h); + g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight())); + g.setComposite(gc.getComposite()); + + if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) { + return false; + } + + ImageSize bufsize = new ImageSize(buf.getWidth(), buf.getHeight(), 72); + + ImageInfo imageInfo = new ImageInfo(null, "image/unknown"); + imageInfo.setSize(bufsize); + + ImageRendered imgRend = new ImageRendered(imageInfo, buf, null); + RenderedImage ri = imgRend.getRenderedImage(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + // Serialize image + // TODO Eventually, this should be changed not to buffer as this + // increases the + // memory consumption (see PostScript output) + ImageEncodingHelper.encodeRenderedImageAsRGB(ri, baos); + } catch (IOException ioe) { + handleIOException(ioe); + return false; + } + + // create image object parameters + AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo(); + imageObjectInfo.setBuffered(true); + if (imageInfo != null) { + imageObjectInfo.setUri(imageInfo.getOriginalURI()); + imageObjectInfo.setMimeType(imageInfo.getMimeType()); + } + + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); + +// float[] srcPts = new float[] {x, y}; +// int[] coords = unitConv.mpts2units(srcPts); +// objectAreaInfo.setX(coords[X]); +// objectAreaInfo.setY(coords[Y]); + AffineTransform at = gc.getTransform(); + float[] srcPts = new float[] {x, y}; + float[] dstPts = new float[2]; + at.transform(srcPts, 0, dstPts, 0, 1); + objectAreaInfo.setX(Math.round(dstPts[X])); + objectAreaInfo.setY(Math.round(dstPts[Y])); + + objectAreaInfo.setWidth(w); + objectAreaInfo.setHeight(h); + + int resolution = state.getResolution(); + objectAreaInfo.setWidthRes(resolution); + objectAreaInfo.setHeightRes(resolution); + + imageObjectInfo.setObjectAreaInfo(objectAreaInfo); + + imageObjectInfo.setData(baos.toByteArray()); + imageObjectInfo.setDataHeight(ri.getHeight()); + imageObjectInfo.setDataWidth(ri.getWidth()); + imageObjectInfo.setColor(state.isColorImages()); + imageObjectInfo.setBitsPerPixel(state.getBitsPerPixel()); + + AFPResourceManager resourceManager = info.getAFPResourceManager(); + try { + resourceManager.createObject(imageObjectInfo); + } catch (IOException ioe) { + log.error(ioe.getMessage()); + return false; + } + return true; } /** {@inheritDoc} */ @@ -442,7 +507,7 @@ public class AFPGraphics2D extends AbstractGraphics2D { * Sets a custom TextHandler implementation that is responsible for painting * text. The default TextHandler paints all text as shapes. A custom * implementation can implement text painting using text painting operators. - * + * * @param handler * the custom TextHandler implementation */ @@ -452,7 +517,7 @@ public class AFPGraphics2D extends AbstractGraphics2D { /** * Returns the GOCA graphics object - * + * * @return the GOCA graphics object */ protected GraphicsObject getGraphicsObject() { @@ -461,11 +526,11 @@ public class AFPGraphics2D extends AbstractGraphics2D { /** * Sets the GOCA graphics object - * + * * @param obj the GOCA graphics object */ public void setGraphicsObject(GraphicsObject obj) { this.graphicsObj = obj; } - + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java index dcd5c7dd5..0f891c03b 100644 --- a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java @@ -25,26 +25,25 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; -import org.apache.xmlgraphics.java2d.Graphics2DImagePainter; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; 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 { - /** logging instance */ - private static Log log = LogFactory.getLog(AFPGraphics2DAdapter.class); + private final AFPRenderer renderer; /** * Main constructor + * + * @param renderer the afp renderer */ - public AFPGraphics2DAdapter() { + public AFPGraphics2DAdapter(AFPRenderer renderer) { + this.renderer = renderer; } /** {@inheritDoc} */ @@ -52,29 +51,60 @@ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter { RendererContext context, int x, int y, int width, int height) throws IOException { - AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context); + // get the 'width' and 'height' attributes of the SVG document + Dimension dim = painter.getImageSize(); final boolean textAsShapes = false; - AFPGraphics2D graphics = new AFPGraphics2D(textAsShapes); - graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); - - if (afpInfo.paintAsBitmap) { + AFPGraphics2D g2d = new AFPGraphics2D(textAsShapes); + + AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context); + g2d.setAFPInfo(afpInfo); + g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); + +// // scale/convert to afp units + AFPState state = afpInfo.getState(); +// AFPUnitConverter unitConv = state.getUnitConverter(); +// float scale = unitConv.mpt2units(1); + + float fwidth = width / 1000f; + float fheight = height / 1000f; + float imw = (float)dim.getWidth() / 1000f; + float imh = (float)dim.getHeight() / 1000f; + float sx = fwidth / imw; + float sy = fheight / imh; +// float fx = x / 1000f; +// float fy = y / 1000f; + AffineTransform at = new AffineTransform(sx, 0, 0, sy, x, y); + + renderer.saveGraphicsState(); + + if (afpInfo.paintAsBitmap()) { //Fallback solution: Paint to a BufferedImage - int resolution = (int)Math.round(context.getUserAgent().getTargetResolution()); + int resolution = Math.round(context.getUserAgent().getTargetResolution()); RendererContextWrapper ctx = RendererContext.wrapRendererContext(context); BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false); - float scale = AFPRenderer.NORMAL_AFP_RESOLUTION + float scale = AFPRenderer.NORMAL_AFP_RESOLUTION / context.getUserAgent().getTargetResolution(); - graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null); - } else { - // get the 'width' and 'height' attributes of the SVG document - Dimension dim = painter.getImageSize(); - float imw = (float)dim.getWidth() / 1000f; - float imh = (float)dim.getHeight() / 1000f; + if (scale != 1) { + at.scale(scale, scale); + } + + AffineTransform trans = state.getData().getTransform(); + trans.concatenate(at); + + // concatenate to transformation matrix +// state.concatenate(at); + + // draw image using current transformation matrix +// at = state.getData().getTransform(); + g2d.drawImage(bi, trans, null); + } else { Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh); - painter.paint(graphics, area); + painter.paint(g2d, area); } + + renderer.restoreGraphicsState(); } } diff --git a/src/java/org/apache/fop/render/afp/GraphicsObjectInfo.java b/src/java/org/apache/fop/render/afp/AFPGraphicsObjectInfo.java index 30214bf4a..c01e266fe 100644 --- a/src/java/org/apache/fop/render/afp/GraphicsObjectInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphicsObjectInfo.java @@ -24,16 +24,16 @@ import org.apache.xmlgraphics.util.MimeConstants; /** * A graphics object info which contains necessary painting objects */ -public class GraphicsObjectInfo extends DataObjectInfo { +public class AFPGraphicsObjectInfo extends AFPDataObjectInfo { - private GraphicsObjectPainter painter; + private AFPGraphicsObjectPainter painter; /** * Returns the graphics painter * * @return the graphics painter */ - public GraphicsObjectPainter getPainter() { + public AFPGraphicsObjectPainter getPainter() { return painter; } @@ -42,7 +42,7 @@ public class GraphicsObjectInfo extends DataObjectInfo { * * @param graphicsPainter the graphics painter */ - public void setPainter(GraphicsObjectPainter graphicsPainter) { + public void setPainter(AFPGraphicsObjectPainter graphicsPainter) { this.painter = graphicsPainter; } diff --git a/src/java/org/apache/fop/render/afp/GraphicsObjectPainter.java b/src/java/org/apache/fop/render/afp/AFPGraphicsObjectPainter.java index c9c9f516a..79788b091 100644 --- a/src/java/org/apache/fop/render/afp/GraphicsObjectPainter.java +++ b/src/java/org/apache/fop/render/afp/AFPGraphicsObjectPainter.java @@ -5,9 +5,9 @@ * 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. @@ -17,24 +17,6 @@ /* $Id$ */ -/* - * 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.batik.gvt.GraphicsNode; @@ -45,41 +27,26 @@ import org.apache.fop.render.afp.modca.GraphicsObject; /** * A simple AFP Graphics 2D painter */ -public class GraphicsObjectPainter { +public class AFPGraphicsObjectPainter { /** Static logging instance */ - protected static Log log = LogFactory.getLog(GraphicsObjectPainter.class); + protected static Log log = LogFactory.getLog(AFPGraphicsObjectPainter.class); + + private final AFPGraphics2D graphics2D; - private AFPGraphics2D graphics2D; - private GraphicsNode root; - - /** - * Default constructor - */ - public GraphicsObjectPainter() { - } - - /** - * Returns the graphics 2D - * - * @return the graphics 2D - */ - public AFPGraphics2D getGraphics2D() { - return graphics2D; - } /** - * Sets the graphics 2D - * - * @param graphics the AFP graphics 2D + * Default constructor + * + * @param graphics the afp graphics 2d implementation */ - public void setGraphics2D(AFPGraphics2D graphics) { + public AFPGraphicsObjectPainter(AFPGraphics2D graphics) { this.graphics2D = graphics; } - + /** * Sets the graphics node - * + * * @param rootNode the graphics root node */ public void setGraphicsNode(GraphicsNode rootNode) { @@ -88,7 +55,7 @@ public class GraphicsObjectPainter { /** * Paints the graphics object - * + * * @param graphicsObj the graphics object */ public void paint(GraphicsObject graphicsObj) { diff --git a/src/java/org/apache/fop/render/afp/ImageObjectInfo.java b/src/java/org/apache/fop/render/afp/AFPImageObjectInfo.java index 6e0f6f58d..b62ea3766 100644 --- a/src/java/org/apache/fop/render/afp/ImageObjectInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPImageObjectInfo.java @@ -5,9 +5,9 @@ * 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. @@ -19,29 +19,29 @@ package org.apache.fop.render.afp; + /** * A list of parameters associated with an image */ -public class ImageObjectInfo extends DataObjectInfo { +public class AFPImageObjectInfo extends AFPDataObjectInfo { private int bitsPerPixel; private boolean color; private int compression = -1; - private byte[] data; private int dataWidth; private int dataHeight; private String mimeType; - private boolean buffered; + private boolean buffered; /** * Default constructor */ - public ImageObjectInfo() { + public AFPImageObjectInfo() { super(); } /** * Sets the number of bits per pixel - * + * * @param bitsPerPixel the number of bits per pixel */ public void setBitsPerPixel(int bitsPerPixel) { @@ -50,7 +50,7 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Sets if this image is color - * + * * @param color true if this is a color image */ public void setColor(boolean color) { @@ -58,17 +58,8 @@ public class ImageObjectInfo extends DataObjectInfo { } /** - * Sets the image data - * - * @param data the image data - */ - public void setData(byte[] data) { - this.data = data; - } - - /** * Sets the image mime type - * + * * @param mimeType the image mime type */ public void setMimeType(String mimeType) { @@ -77,16 +68,16 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Returns the number of bits used per pixel - * + * * @return the number of bits used per pixel */ public int getBitsPerPixel() { return bitsPerPixel; } - + /** * Returns true if this is a color image - * + * * @return true if this is a color image */ public boolean isColor() { @@ -94,44 +85,35 @@ public class ImageObjectInfo extends DataObjectInfo { } /** - * Returns the image data - * - * @return the image data - */ - public byte[] getData() { - return data; - } - - /** * Returns true if this image uses compression - * + * * @return true if this image uses compression */ public boolean hasCompression() { return compression > -1; } - + /** * Returns the compression type - * + * * @return the compression type */ public int getCompression() { return compression; } - + /** * Sets the compression used with this image - * + * * @param compression the type of compression used with this image */ public void setCompression(int compression) { this.compression = compression; } - + /** * Returns the image data width - * + * * @return the image data width */ public int getDataWidth() { @@ -140,7 +122,7 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Sets the image data width - * + * * @param imageDataWidth the image data width */ public void setDataWidth(int imageDataWidth) { @@ -149,7 +131,7 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Returns the image data height - * + * * @return the image data height */ public int getDataHeight() { @@ -158,7 +140,7 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Sets the image data height - * + * * @param imageDataHeight the image data height */ public void setDataHeight(int imageDataHeight) { @@ -172,7 +154,7 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Sets whether or not this is info about a buffered image - * + * * @param buffered true if this is info about a buffered image */ public void setBuffered(boolean buffered) { @@ -181,16 +163,16 @@ public class ImageObjectInfo extends DataObjectInfo { /** * Returns true if this image info is about a buffered image - * + * * @return true if this image info is about a buffered image */ public boolean isBuffered() { return this.buffered; } - + /** {@inheritDoc} */ public String toString() { - return "ImageObjectInfo{" + super.toString() + return "AFPImageObjectInfo{" + super.toString() + ", dataWidth=" + dataWidth + ", dataHeight=" + dataHeight + ", color=" + color diff --git a/src/java/org/apache/fop/render/afp/AFPInfo.java b/src/java/org/apache/fop/render/afp/AFPInfo.java index 9a84ffa52..626428a97 100644 --- a/src/java/org/apache/fop/render/afp/AFPInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPInfo.java @@ -5,9 +5,9 @@ * 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. @@ -21,7 +21,6 @@ package org.apache.fop.render.afp; import org.apache.avalon.framework.configuration.Configuration; import org.apache.fop.fonts.FontInfo; -import org.apache.fop.render.afp.modca.AFPDataStream; /** * AFP information structure for drawing the XML document. @@ -45,18 +44,18 @@ public final class AFPInfo { /** see AFP_FONT_INFO */ private FontInfo fontInfo; - /** See AFP_DATASTREAM */ - private AFPDataStream afpDataStream; - /** See AFP_STATE */ - private AFPState afpState; + private AFPState state; + + /** See AFP_RESOURCE_MANAGER */ + private AFPResourceManager resourceManager; /** true if SVG should be rendered as a bitmap instead of natively */ - public boolean paintAsBitmap; - + private boolean paintAsBitmap; + /** * Returns the width. - * + * * @return the width */ public int getWidth() { @@ -65,7 +64,7 @@ public final class AFPInfo { /** * Sets the width. - * + * * @param width The pageWidth to set */ public void setWidth(int width) { @@ -74,7 +73,7 @@ public final class AFPInfo { /** * Returns the height. - * + * * @return the height */ public int getHeight() { @@ -83,7 +82,7 @@ public final class AFPInfo { /** * Sets the height. - * + * * @param height The height to set */ public void setHeight(int height) { @@ -92,7 +91,7 @@ public final class AFPInfo { /** * Returns the handler configuration - * + * * @return the handler configuration */ public Configuration getHandlerConfiguration() { @@ -101,16 +100,16 @@ public final class AFPInfo { /** * Sets the handler configuration - * + * * @param cfg the handler configuration */ public void setHandlerConfiguration(Configuration cfg) { this.cfg = cfg; } - + /** * Return the font info - * + * * @return the font info */ public FontInfo getFontInfo() { @@ -119,25 +118,25 @@ public final class AFPInfo { /** * Returns the current AFP state - * + * * @return the current AFP state */ public AFPState getState() { - return this.afpState; + return this.state; } /** - * Returns the AFPDataStream the afp datastream - * - * @return the AFPDataStream the afp datastream + * Returns the AFPResourceManager + * + * @return the AFPResourceManager */ - public AFPDataStream getAFPDataStream() { - return this.afpDataStream; + public AFPResourceManager getAFPResourceManager() { + return this.resourceManager; } - + /** * Returns true if supports color - * + * * @return true if supports color */ public boolean isColorSupported() { @@ -146,7 +145,7 @@ public final class AFPInfo { /** * Returns the current x position coordinate - * + * * @return the current x position coordinate */ protected int getX() { @@ -155,7 +154,7 @@ public final class AFPInfo { /** * Returns the current y position coordinate - * + * * @return the current y position coordinate */ protected int getY() { @@ -164,7 +163,7 @@ public final class AFPInfo { /** * Returns the resolution - * + * * @return the resolution */ protected int getResolution() { @@ -181,7 +180,7 @@ public final class AFPInfo { /** * Sets the current x position coordinate - * + * * @param x the current x position coordinate */ protected void setX(int x) { @@ -190,7 +189,7 @@ public final class AFPInfo { /** * Sets the current y position coordinate - * + * * @param y the current y position coordinate */ protected void setY(int y) { @@ -199,7 +198,7 @@ public final class AFPInfo { /** * Sets the current font info - * + * * @param fontInfo the current font info */ protected void setFontInfo(FontInfo fontInfo) { @@ -208,32 +207,52 @@ public final class AFPInfo { /** * Sets the AFP state - * + * * @param state the AFP state */ public void setState(AFPState state) { - this.afpState = state; + this.state = state; } - + /** - * Sets the AFP datastream - * - * @param dataStream the AFP datastream + * Sets the AFPResourceManager + * + * @param resourceManager the AFPResourceManager */ - public void setAFPDataStream(AFPDataStream dataStream) { - this.afpDataStream = dataStream; + 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; } - /** {@inheritDoc} */ public String toString() { - return "width=" + width - + ",height=" + height - + ",x=" + x - + ",y=" + y - + ",cfg=" + cfg - + ",fontInfo=" + fontInfo - + ",afpDatastream=" + afpDataStream - + ",afpState=" + afpState; + return "AFPInfo{width=" + width + + ", height=" + height + + ", x=" + x + + ", y=" + y + + ", cfg=" + cfg + + ", fontInfo=" + fontInfo + + ", resourceManager=" + resourceManager + + ", state=" + state + + ", paintAsBitmap=" + paintAsBitmap + + "}"; } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/ObjectAreaInfo.java b/src/java/org/apache/fop/render/afp/AFPObjectAreaInfo.java index 7c654519b..2f7f61d38 100644 --- a/src/java/org/apache/fop/render/afp/ObjectAreaInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPObjectAreaInfo.java @@ -23,7 +23,7 @@ package org.apache.fop.render.afp; * A common class used to convey locations, * dimensions and resolutions of data objects. */ -public class ObjectAreaInfo { +public class AFPObjectAreaInfo { private int x; private int y; private int width; @@ -31,10 +31,12 @@ public class ObjectAreaInfo { private int widthRes; private int heightRes; private int rotation = 0; + private int offsetX; + private int offsetY; /** * Sets the x position of the data object - * + * * @param x the x position of the data object */ public void setX(int x) { @@ -43,7 +45,7 @@ public class ObjectAreaInfo { /** * Sets the y position of the data object - * + * * @param y the y position of the data object */ public void setY(int y) { @@ -52,7 +54,7 @@ public class ObjectAreaInfo { /** * Sets the data object width - * + * * @param width the width of the data object */ public void setWidth(int width) { @@ -61,7 +63,7 @@ public class ObjectAreaInfo { /** * Sets the data object height - * + * * @param height the height of the data object */ public void setHeight(int height) { @@ -70,7 +72,7 @@ public class ObjectAreaInfo { /** * Sets the width resolution - * + * * @param widthRes the width resolution */ public void setWidthRes(int widthRes) { @@ -79,7 +81,7 @@ public class ObjectAreaInfo { /** * Sets the height resolution - * + * * @param heightRes the height resolution */ public void setHeightRes(int heightRes) { @@ -88,7 +90,7 @@ public class ObjectAreaInfo { /** * Returns the x coordinate of this data object - * + * * @return the x coordinate of this data object */ public int getX() { @@ -97,7 +99,7 @@ public class ObjectAreaInfo { /** * Returns the y coordinate of this data object - * + * * @return the y coordinate of this data object */ public int getY() { @@ -106,7 +108,7 @@ public class ObjectAreaInfo { /** * Returns the width of this data object - * + * * @return the width of this data object */ public int getWidth() { @@ -115,7 +117,7 @@ public class ObjectAreaInfo { /** * Returns the height of this data object - * + * * @return the height of this data object */ public int getHeight() { @@ -124,7 +126,7 @@ public class ObjectAreaInfo { /** * Returns the width resolution of this data object - * + * * @return the width resolution of this data object */ public int getWidthRes() { @@ -133,7 +135,7 @@ public class ObjectAreaInfo { /** * Returns the height resolution of this data object - * + * * @return the height resolution of this data object */ public int getHeightRes() { @@ -142,7 +144,7 @@ public class ObjectAreaInfo { /** * Returns the rotation of this data object - * + * * @return the rotation of this data object */ public int getRotation() { @@ -151,7 +153,7 @@ public class ObjectAreaInfo { /** * Sets the data object rotation - * + * * @param rotation the data object rotation */ public void setRotation(int rotation) { @@ -168,4 +170,21 @@ public class ObjectAreaInfo { + ", heightRes=" + heightRes + ", rotation=" + rotation; } + +// public int getOffsetX() { +// return offsetX; +// } +// +// public int getOffsetY() { +// return offsetY; +// } +// +// public void setOffsetX(int afpx) { +// this.offsetX = afpx; +// } +// +// public void setOffsetY(int afpy) { +// this.offsetY = afpy; +// } + } diff --git a/src/java/org/apache/fop/render/afp/AFPPageFonts.java b/src/java/org/apache/fop/render/afp/AFPPageFonts.java index e09167ff5..1bcbbb51d 100644 --- a/src/java/org/apache/fop/render/afp/AFPPageFonts.java +++ b/src/java/org/apache/fop/render/afp/AFPPageFonts.java @@ -5,9 +5,9 @@ * 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. @@ -22,13 +22,30 @@ package org.apache.fop.render.afp; import org.apache.fop.render.afp.fonts.AFPFont; /** - * Holds the current page fonts + * Holds the current page fonts */ public class AFPPageFonts extends java.util.HashMap { private static final long serialVersionUID = -4991896259427109041L; /** + * Default constructor + */ + public AFPPageFonts() { + super(); + } + + /** + * Parameterized constructor + * + * @param fonts an existing set of afp page fonts + */ + public AFPPageFonts(AFPPageFonts fonts) { + super(fonts); + } + + /** * Registers a font on the current page and returns font attributes + * * @param fontName the internal font name * @param font the AFPFont * @param fontSize the font point size diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java index 6d4e8fafd..adc67d037 100644 --- a/src/java/org/apache/fop/render/afp/AFPRenderer.java +++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java @@ -36,19 +36,6 @@ import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; - -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.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.MimeConstants; @@ -63,7 +50,6 @@ import org.apache.fop.area.inline.Leader; import org.apache.fop.area.inline.TextArea; 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; @@ -76,9 +62,20 @@ 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.AFPDataStream; +import org.apache.fop.render.afp.modca.DataStream; 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.impl.ImageGraphics2D; +import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax; +import org.apache.xmlgraphics.image.loader.impl.ImageRawStream; +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; /** * This is an implementation of a FOP Renderer that renders areas to AFP. @@ -140,40 +137,37 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { public static final int NORMAL_AFP_RESOLUTION = 72; private static final int X = 0; - private static final int Y = 1; - private static final int X1 = 0; + /** resource manager */ + private AFPResourceManager resourceManager; - private static final int Y1 = 1; - - private static final int X2 = 2; + /** drawing state */ + private final AFPState state; - private static final int Y2 = 3; + /** unit converter */ + private final AFPUnitConverter unitConv; - /** - * The afp data stream object responsible for generating afp data - */ - private AFPDataStream afpDataStream = null; + /** line painter */ + private AFPBorderPainter borderPainter; - /** - * The map of page segments - */ - private Map/*<String,String>*/pageSegmentsMap = null; + /** The map of page segments */ + private final Map/*<String,String>*/pageSegmentMap = new java.util.HashMap/*<String,String>*/(); - /** - * The map of saved incomplete pages - */ - private Map pages = null; + /** The map of saved incomplete pages */ + private final Map pages = new java.util.HashMap/*<PageViewport,PageObject>*/(); - /** drawing state */ - private AFPState currentState = new AFPState(); + /** the afp datastream */ + private DataStream dataStream; /** * Constructor for AFPRenderer. */ public AFPRenderer() { super(); + this.resourceManager = new AFPResourceManager(); + this.state = new AFPState(); + this.unitConv = state.getUnitConverter(); } /** {@inheritDoc} */ @@ -193,22 +187,31 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void startRenderer(OutputStream outputStream) throws IOException { - currentState.setColor(new Color(255, 255, 255)); - getAFPDataStream().setPortraitRotation(currentState.getPortraitRotation()); - afpDataStream.setLandscapeRotation(currentState.getLandscapeRotation()); - afpDataStream.setOutputStream(outputStream); + state.setColor(new Color(255, 255, 255)); + resourceManager.setOutputStream(outputStream); + + this.dataStream = resourceManager.getDataStream(); + dataStream.setPortraitRotation(state.getPortraitRotation()); + dataStream.setLandscapeRotation(state.getLandscapeRotation()); + dataStream.startDocument(); + + this.borderPainter = new AFPBorderPainter(state, dataStream); } /** {@inheritDoc} */ public void stopRenderer() throws IOException { - getAFPDataStream().write(); - afpDataStream = null; + dataStream.endDocument(); + resourceManager.writeToStream(); + resourceManager = null; } /** {@inheritDoc} */ public void startPageSequence(LineArea seqTitle) { - getAFPDataStream().endPageGroup(); - afpDataStream.startPageGroup(); + try { + dataStream.startPageGroup(); + } catch (IOException e) { + log.error(e.getMessage()); + } } /** {@inheritDoc} */ @@ -219,22 +222,16 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void preparePage(PageViewport page) { final int pageRotation = 0; - int pageWidth = currentState.getPageWidth(); - int pageHeight = currentState.getPageHeight(); - getAFPDataStream().startPage(pageWidth, pageHeight, pageRotation, - getResolution(), getResolution()); + int pageWidth = state.getPageWidth(); + int pageHeight = state.getPageHeight(); + int resolution = state.getResolution(); + dataStream.startPage(pageWidth, pageHeight, pageRotation, + resolution, resolution); renderPageObjectExtensions(page); - PageObject currentPage = getAFPDataStream().savePage(); - getPages().put(page, currentPage); - } - - private Map/*<PageViewport, PageObject>*/ getPages() { - if (this.pages == null) { - this.pages = new java.util.HashMap/*<PageViewport, PageObject>*/(); - } - return this.pages; + PageObject currentPage = dataStream.savePage(); + pages.put(page, currentPage); } /** {@inheritDoc} */ @@ -245,7 +242,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public Graphics2DAdapter getGraphics2DAdapter() { - return new AFPGraphics2DAdapter(); + return new AFPGraphics2DAdapter(this); } /** {@inheritDoc} */ @@ -271,36 +268,44 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ protected void concatenateTransformationMatrix(AffineTransform at) { if (!at.isIdentity()) { - currentState.concatenate(at); + state.concatenate(at); } } + /** + * Returns the base AFP transform + * + * @return the base AFP transform + */ + private AffineTransform getBaseTransform() { + AffineTransform baseTransform = new AffineTransform(); + double scale = unitConv.mpt2units(1); + baseTransform.scale(scale, scale); + return baseTransform; + } + /** {@inheritDoc} */ public void renderPage(PageViewport pageViewport) throws IOException, FOPException { - currentState.clear(); + state.clear(); Rectangle2D bounds = pageViewport.getViewArea(); - AffineTransform basicPageTransform = new AffineTransform(); - int resolution = currentState.getResolution(); - double scale = mpt2units(1); - basicPageTransform.scale(scale, scale); + state.concatenate(getBaseTransform()); - currentState.concatenate(basicPageTransform); - - if (getPages().containsKey(pageViewport)) { - getAFPDataStream().restorePage( - (PageObject)getPages().remove(pageViewport)); + if (pages.containsKey(pageViewport)) { + dataStream.restorePage( + (PageObject)pages.remove(pageViewport)); } else { int pageWidth - = (int)Math.round(mpt2units((float)bounds.getWidth())); - currentState.setPageWidth(pageWidth); + = Math.round(unitConv.mpt2units((float)bounds.getWidth())); + state.setPageWidth(pageWidth); int pageHeight - = (int)Math.round(mpt2units((float)bounds.getHeight())); - currentState.setPageHeight(pageHeight); + = Math.round(unitConv.mpt2units((float)bounds.getHeight())); + state.setPageHeight(pageHeight); final int pageRotation = 0; - getAFPDataStream().startPage(pageWidth, pageHeight, pageRotation, + int resolution = state.getResolution(); + dataStream.startPage(pageWidth, pageHeight, pageRotation, resolution, resolution); renderPageObjectExtensions(pageViewport); @@ -308,12 +313,12 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { super.renderPage(pageViewport); - AFPPageFonts pageFonts = currentState.getPageFonts(); + AFPPageFonts pageFonts = state.getPageFonts(); if (pageFonts != null && !pageFonts.isEmpty()) { - getAFPDataStream().addFontsToCurrentPage(pageFonts); + dataStream.addFontsToCurrentPage(pageFonts); } - getAFPDataStream().endPage(); + dataStream.endPage(); } /** {@inheritDoc} */ @@ -347,220 +352,15 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { log.debug("NYI closePath()"); } - private int[] mpts2units(float[] srcPts, float[] dstPts) { - return transformPoints(srcPts, dstPts, true); - } - - private int[] pts2units(float[] srcPts, float[] dstPts) { - return transformPoints(srcPts, dstPts, false); - } - - private int[] mpts2units(float[] srcPts) { - return transformPoints(srcPts, null, true); - } - - private int[] pts2units(float[] srcPts) { - return transformPoints(srcPts, null, false); - } - - private float mpt2units(float mpt) { - return mpt / ((float)AFPConstants.DPI_72_MPTS / currentState.getResolution()); - } - /** {@inheritDoc} */ public void fillRect(float x, float y, float width, float height) { - float[] srcPts = new float[] {x * 1000, y * 1000}; - float[] dstPts = new float[srcPts.length]; - int[] coords = mpts2units(srcPts, dstPts); - int x2 = Math.round(mpt2units(dstPts[X] + width * 1000)); - LineDataInfo lineDataInfo = new LineDataInfo(); - lineDataInfo.x1 = coords[X]; - lineDataInfo.y1 = coords[Y]; - lineDataInfo.x2 = x2; - lineDataInfo.y2 = coords[Y]; - lineDataInfo.thickness = Math.round(mpt2units(height * 1000)); - lineDataInfo.color = currentState.getColor(); - getAFPDataStream().createLine(lineDataInfo); + borderPainter.fillRect(x, y, width, height); } /** {@inheritDoc} */ public void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz, boolean startOrBefore, int style, Color col) { - float[] srcPts = new float[] {x1 * 1000, y1 * 1000, x2 * 1000, y2 * 1000}; - float[] dstPts = new float[srcPts.length]; - int[] coords = mpts2units(srcPts, dstPts); - - float width = dstPts[X2] - dstPts[X1]; - float height = dstPts[Y2] - dstPts[Y1]; - if ((width < 0) || (height < 0)) { - log.error("Negative extent received. Border won't be painted."); - return; - } - - LineDataInfo lineDataInfo = new LineDataInfo(); - lineDataInfo.color = col; - - switch (style) { - - case Constants.EN_DOUBLE: - - lineDataInfo.x1 = coords[X1]; - lineDataInfo.y1 = coords[Y1]; - - if (horz) { - float h3 = height / 3; - lineDataInfo.thickness = Math.round(h3); - - lineDataInfo.x2 = coords[X2]; - lineDataInfo.y2 = coords[Y1]; - afpDataStream.createLine(lineDataInfo); - - int ym2 = Math.round(dstPts[Y1] + h3 + h3); - lineDataInfo.y1 = ym2; - lineDataInfo.y2 = ym2; - afpDataStream.createLine(lineDataInfo); - } else { - float w3 = width / 3; - lineDataInfo.thickness = Math.round(w3); - - lineDataInfo.x2 = coords[X1]; - lineDataInfo.y2 = coords[Y2]; - afpDataStream.createLine(lineDataInfo); - - int xm2 = Math.round(dstPts[X1] + w3 + w3); - lineDataInfo.x1 = xm2; - lineDataInfo.x2 = xm2; - afpDataStream.createLine(lineDataInfo); - } - break; - - case Constants.EN_DASHED: - lineDataInfo.x1 = coords[X1]; - - if (horz) { - float w2 = 2 * height; - - lineDataInfo.y1 = coords[Y1]; - lineDataInfo.x2 = coords[X1] + Math.round(w2); - lineDataInfo.y2 = coords[Y1]; - lineDataInfo.thickness = Math.round(height); - - while (lineDataInfo.x1 + w2 < coords[X2]) { - afpDataStream.createLine(lineDataInfo); - lineDataInfo.x1 += 2 * w2; - } - } else { - float h2 = 2 * width; - - lineDataInfo.y1 = coords[Y2]; - lineDataInfo.x2 = coords[X1]; - lineDataInfo.y2 = coords[Y1] + Math.round(h2); - lineDataInfo.thickness = Math.round(width); - - while (lineDataInfo.y2 < coords[Y2]) { - afpDataStream.createLine(lineDataInfo); - lineDataInfo.y2 += 2 * h2; - } - } - break; - - case Constants.EN_DOTTED: - - lineDataInfo.x1 = coords[X1]; - lineDataInfo.y1 = coords[Y1]; - - if (horz) { - lineDataInfo.thickness = Math.round(height); - lineDataInfo.x2 = coords[X1] + lineDataInfo.thickness; - lineDataInfo.y2 = coords[Y1]; - while (lineDataInfo.x2 < coords[X2]) { - afpDataStream.createLine(lineDataInfo); - coords[X1] += 2 * height; - lineDataInfo.x1 = coords[X1]; - lineDataInfo.x2 = coords[X1] + lineDataInfo.thickness; - } - } else { - lineDataInfo.thickness = Math.round(width); - lineDataInfo.x2 = coords[X1]; - lineDataInfo.y2 = coords[Y1] + lineDataInfo.thickness; - - while (lineDataInfo.y2 < coords[Y2]) { - afpDataStream.createLine(lineDataInfo); - coords[Y1] += 2 * width; - lineDataInfo.y1 = coords[Y1]; - lineDataInfo.y2 = coords[Y1] + lineDataInfo.thickness; - } - } - break; - case Constants.EN_GROOVE: - case Constants.EN_RIDGE: { - - float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f); - if (horz) { - - lineDataInfo.x1 = coords[X1]; - lineDataInfo.x2 = coords[X2]; - - float h3 = height / 3; - - lineDataInfo.color = ColorUtil.lightenColor(col, -colFactor); - lineDataInfo.thickness = Math.round(h3); - lineDataInfo.y1 = lineDataInfo.y2 = coords[Y1]; - afpDataStream.createLine(lineDataInfo); - - lineDataInfo.color = col; - lineDataInfo.y1 = lineDataInfo.y2 = Math.round(dstPts[Y1] + h3); - afpDataStream.createLine(lineDataInfo); - - lineDataInfo.color = ColorUtil.lightenColor(col, colFactor); - lineDataInfo.y1 = lineDataInfo.y2 - = Math.round(dstPts[Y1] + h3 + h3); - afpDataStream.createLine(lineDataInfo); - - } else { - - lineDataInfo.y1 = coords[Y1]; - lineDataInfo.y2 = coords[Y2]; - - float w3 = width / 3; - float xm1 = dstPts[X1] + (w3 / 2); - - lineDataInfo.color = ColorUtil.lightenColor(col, -colFactor); - lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1); - afpDataStream.createLine(lineDataInfo); - - lineDataInfo.color = col; - lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1 + w3); - afpDataStream.createLine(lineDataInfo); - - lineDataInfo.color = ColorUtil.lightenColor(col, colFactor); - lineDataInfo.x1 = lineDataInfo.x2 = Math.round(xm1 + w3 + w3); - afpDataStream.createLine(lineDataInfo); - } - break; - } - - case Constants.EN_HIDDEN: - break; - - case Constants.EN_INSET: - case Constants.EN_OUTSET: - default: - lineDataInfo.x1 = coords[X1]; - lineDataInfo.y1 = coords[Y1]; - if (horz) { - lineDataInfo.thickness = Math.round(height); - lineDataInfo.x2 = coords[X2]; - lineDataInfo.y2 = coords[Y1]; - } else { - lineDataInfo.thickness = Math.round(width); - lineDataInfo.x2 = coords[X1]; - lineDataInfo.y2 = coords[Y2]; - } - lineDataInfo.x2 = (horz ? coords[X2] : coords[X1]); - lineDataInfo.y2 = (horz ? coords[Y1] : coords[Y2]); - afpDataStream.createLine(lineDataInfo); - } + borderPainter.drawBorderLine(x1, y1, x2, y2, horz, startOrBefore, style, col); } /** {@inheritDoc} */ @@ -571,129 +371,82 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { foreignAttributes); context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO, this.fontInfo); - context.setProperty(AFPRendererContextConstants.AFP_DATASTREAM, - getAFPDataStream()); - context.setProperty(AFPRendererContextConstants.AFP_STATE, getState()); + context.setProperty(AFPRendererContextConstants.AFP_RESOURCE_MANAGER, + this.resourceManager); + context.setProperty(AFPRendererContextConstants.AFP_STATE, state); return context; } private static final ImageFlavor[] FLAVORS = new ImageFlavor[] { - ImageFlavor.RAW_CCITTFAX, ImageFlavor.GRAPHICS2D, - ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE, - ImageFlavor.XML_DOM }; + ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.GRAPHICS2D, + ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE, + ImageFlavor.XML_DOM, /*ImageFlavor.RAW_EPS*/ }; /** {@inheritDoc} */ public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) { uri = URISpecification.getURL(uri); - currentState.setImageUri(uri); + state.setImageUri(uri); Rectangle posInt = new Rectangle((int) pos.getX(), (int) pos.getY(), (int) pos.getWidth(), (int) pos.getHeight()); - Point origin = new Point(currentIPPosition, currentBPPosition); - int x = origin.x + posInt.x; - int y = origin.y + posInt.y; - - String name = (String)getPageSegments().get(uri); + String name = (String)pageSegmentMap.get(uri); + int x = currentIPPosition + posInt.x; + int y = currentBPPosition + posInt.y; + float[] srcPts = {x, y}; + int[] coords = unitConv.mpts2units(srcPts); if (name != null) { - float[] srcPts = {x, y}; - int[] coords = mpts2units(srcPts); - getAFPDataStream().createIncludePageSegment(name, coords[X], coords[Y]); + dataStream.createIncludePageSegment(name, coords[X], coords[Y]); } else { - ImageManager manager = getUserAgent().getFactory().getImageManager(); + Point origin = new Point(currentIPPosition, currentBPPosition); + + ImageManager manager = userAgent.getFactory().getImageManager(); ImageInfo info = null; InputStream in = null; try { - ImageSessionContext sessionContext = getUserAgent() + ImageSessionContext sessionContext = userAgent .getImageSessionContext(); info = manager.getImageInfo(uri, sessionContext); // Only now fully load/prepare the image Map hints = ImageUtil.getDefaultHints(sessionContext); - org.apache.xmlgraphics.image.loader.Image img = manager - .getImage(info, FLAVORS, hints, sessionContext); - - // ...and process the image - if (img instanceof ImageGraphics2D) { + org.apache.xmlgraphics.image.loader.Image img = manager.getImage( + info, FLAVORS, hints, sessionContext); + + if (/*img instanceof ImageRawJPEG || */img instanceof ImageRawStream + || img instanceof ImageRendered) { + AFPImageObjectInfo imageObjectInfo + = getImageObjectInfo(uri, info, pos, origin, img); + resourceManager.createObject(imageObjectInfo); + } else if (img instanceof ImageGraphics2D) { // ...and process the image ImageGraphics2D imageG2D = (ImageGraphics2D) img; - RendererContext context = createRendererContext(posInt.x, - posInt.y, posInt.width, posInt.height, - foreignAttributes); + RendererContext rendererContext = createRendererContext( + x, 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(info, ri, getResolution(), posInt.x - + currentIPPosition, posInt.y + currentBPPosition, - posInt.width, posInt.height, foreignAttributes); - } else if (img instanceof ImageRawCCITTFax) { - ImageRawCCITTFax ccitt = (ImageRawCCITTFax) img; - in = ccitt.createInputStream(); - byte[] buf = IOUtils.toByteArray(in); - float[] srcPts = new float[] { - posInt.x + currentIPPosition, - posInt.y + currentBPPosition, - (float)posInt.getWidth(), - (float)posInt.getHeight() - }; - int[] coords = mpts2units(srcPts); - - // create image object parameters - ImageObjectInfo imageObjectInfo = new ImageObjectInfo(); - imageObjectInfo.setBuffered(false); - imageObjectInfo.setUri(uri); - - String mimeType = info.getMimeType(); - if (mimeType != null) { - imageObjectInfo.setMimeType(mimeType); - } - - ObjectAreaInfo objectAreaInfo = new ObjectAreaInfo(); - objectAreaInfo.setX(coords[X]); - objectAreaInfo.setY(coords[Y]); - int resolution = currentState.getResolution(); - int w = Math.round(mpt2units((float)posInt.getWidth() * 1000)); - int h = Math.round(mpt2units((float)posInt.getHeight() * 1000)); - objectAreaInfo.setWidth(w); - objectAreaInfo.setHeight(h); - objectAreaInfo.setWidthRes(resolution); - objectAreaInfo.setHeightRes(resolution); - imageObjectInfo.setObjectAreaInfo(objectAreaInfo); - - imageObjectInfo.setData(buf); - imageObjectInfo.setDataHeight(ccitt.getSize().getHeightPx()); - imageObjectInfo.setDataWidth(ccitt.getSize().getWidthPx()); - imageObjectInfo.setColor(currentState.isColorImages()); - imageObjectInfo.setBitsPerPixel(currentState.getBitsPerPixel()); - imageObjectInfo.setCompression(ccitt.getCompression()); - imageObjectInfo.setResourceInfoFromForeignAttributes(foreignAttributes); - - getAFPDataStream().createObject(imageObjectInfo); + imageG2D.getGraphics2DImagePainter(), rendererContext, + origin.x + posInt.x, origin.y + posInt.y, posInt.width, + posInt.height); } else if (img instanceof ImageXMLDOM) { ImageXMLDOM imgXML = (ImageXMLDOM) img; - renderDocument(imgXML.getDocument(), imgXML - .getRootNamespace(), pos, foreignAttributes); + renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(), + posInt, foreignAttributes); } else { throw new UnsupportedOperationException( "Unsupported image type: " + img); } - } catch (ImageException ie) { ResourceEventProducer eventProducer = ResourceEventProducer.Provider - .get(getUserAgent().getEventBroadcaster()); + .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); + .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); + .get(userAgent.getEventBroadcaster()); + eventProducer.imageIOError(this, (info != null ? info.toString() + : uri), ioe, null); } finally { if (in != null) { IOUtils.closeQuietly(in); @@ -703,6 +456,106 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** + * Gets the AFP image object information for a given image + * + * @param uri the image uri + * @param info the image info + * @param pos the image content area + * @param origin the current position + * @param img the image + * @return an image object info + * @throws IOException thrown if an I/O exception of some sort has occurred + */ + private AFPImageObjectInfo getImageObjectInfo(String uri, ImageInfo info, Rectangle2D pos, + Point origin, org.apache.xmlgraphics.image.loader.Image img) throws IOException { + AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo(); + imageObjectInfo.setUri(uri); + imageObjectInfo.setColor(state.isColorImages()); + imageObjectInfo.setBitsPerPixel(state.getBitsPerPixel()); + imageObjectInfo.setMimeType(info.getMimeType()); + + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); + + float srcX = origin.x + (float)pos.getX(); + float srcY = origin.y + (float)pos.getY(); + int[] coords = unitConv.mpts2units(new float[] {srcX, srcY}); + objectAreaInfo.setX(coords[X]); + objectAreaInfo.setY(coords[Y]); + + int width = Math.round(unitConv.mpt2units((float)pos.getWidth())); + objectAreaInfo.setWidth(width); + + int height = Math.round(unitConv.mpt2units((float)pos.getHeight())); + objectAreaInfo.setHeight(height); + + String mimeType = info.getMimeType(); + if (mimeType != null) { + imageObjectInfo.setMimeType(mimeType); + } + imageObjectInfo.setObjectAreaInfo(objectAreaInfo); + + if (img instanceof ImageRendered) { + imageObjectInfo.setBuffered(true); + + ImageRendered imageRendered = (ImageRendered) img; + RenderedImage renderedImage = imageRendered.getRenderedImage(); + + 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) + ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baout); + } catch (IOException ioe) { + ResourceEventProducer eventProducer = ResourceEventProducer.Provider + .get(userAgent.getEventBroadcaster()); + eventProducer.imageWritingError(this, ioe); + throw ioe; + } + imageObjectInfo.setData(baout.toByteArray()); + + int resolution = state.getResolution(); + objectAreaInfo.setWidthRes(resolution); + objectAreaInfo.setHeightRes(resolution); + + imageObjectInfo.setDataHeight(renderedImage.getHeight()); + imageObjectInfo.setDataWidth(renderedImage.getWidth()); + } else { + imageObjectInfo.setBuffered(false); + +// int resolution = state.getResolution(); +// objectAreaInfo.setWidthRes(resolution); +// objectAreaInfo.setHeightRes(resolution); + + ImageRawStream rawStream = (ImageRawStream) img; + + int xresol = (int) (rawStream.getSize().getDpiHorizontal() * 10); + objectAreaInfo.setWidthRes(xresol); + + int yresol = (int) (rawStream.getSize().getDpiVertical() * 10); + objectAreaInfo.setHeightRes(yresol); + + InputStream inputStream = rawStream.createInputStream(); + byte[] buf = IOUtils.toByteArray(inputStream); + imageObjectInfo.setData(buf); + + int dataHeight = rawStream.getSize().getHeightPx(); + imageObjectInfo.setDataHeight(dataHeight); + + int dataWidth = rawStream.getSize().getWidthPx(); + imageObjectInfo.setDataWidth(dataWidth); + + if (img instanceof ImageRawCCITTFax) { + ImageRawCCITTFax ccitt = (ImageRawCCITTFax) img; + imageObjectInfo.setCompression(ccitt.getCompression()); + } + } + return imageObjectInfo; + } + + /** * Writes a RenderedImage to an OutputStream as raw sRGB bitmaps. * * @param image @@ -719,80 +572,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { ImageEncodingHelper.encodeRenderedImageAsRGB(image, out); } - /** - * Draws a BufferedImage to AFP. - * - * @param imageInfo - * the image info - * @param image - * the RenderedImage - * @param imageRes - * the resolution of the BufferedImage - * @param x - * the x coordinate (in mpt) - * @param y - * the y coordinate (in mpt) - * @param width - * the width of the viewport (in mpt) - * @param height - * the height of the viewport (in mpt) - * @param foreignAttributes - * a mapping of foreign attributes - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public void drawBufferedImage(ImageInfo imageInfo, RenderedImage image, - int imageRes, int x, int y, int width, int height, Map foreignAttributes) throws IOException { - 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) - ImageEncodingHelper.encodeRenderedImageAsRGB(image, baout); - } catch (IOException ioe) { - ResourceEventProducer eventProducer = ResourceEventProducer.Provider - .get(getUserAgent().getEventBroadcaster()); - eventProducer.imageWritingError(this, ioe); - return; - } - - // create image object parameters - ImageObjectInfo imageObjectInfo = new ImageObjectInfo(); - imageObjectInfo.setBuffered(true); - if (imageInfo != null) { - imageObjectInfo.setUri(imageInfo.getOriginalURI()); - imageObjectInfo.setMimeType(imageInfo.getMimeType()); - } - - ObjectAreaInfo objectAreaInfo = new ObjectAreaInfo(); - - float[] srcPts = new float[] {x, y}; - int[] coords = mpts2units(srcPts); - objectAreaInfo.setX(coords[X]); - objectAreaInfo.setY(coords[Y]); - int w = Math.round(mpt2units(width)); - int h = Math.round(mpt2units(height)); - objectAreaInfo.setWidth(w); - objectAreaInfo.setHeight(h); - - objectAreaInfo.setWidthRes(imageRes); - objectAreaInfo.setHeightRes(imageRes); - imageObjectInfo.setObjectAreaInfo(objectAreaInfo); - - imageObjectInfo.setData(baout.toByteArray()); - imageObjectInfo.setDataHeight(image.getHeight()); - imageObjectInfo.setDataWidth(image.getWidth()); - imageObjectInfo.setColor(currentState.isColorImages()); - imageObjectInfo.setBitsPerPixel(currentState.getBitsPerPixel()); - imageObjectInfo.setResourceInfoFromForeignAttributes(foreignAttributes); - - getAFPDataStream().createObject(imageObjectInfo); - } - /** {@inheritDoc} */ public void updateColor(Color col, boolean fill) { if (fill) { - currentState.setColor(col); + state.setColor(col); } } @@ -814,8 +597,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { List breakOutList = new java.util.ArrayList(); AbstractState.AbstractData data; while (true) { - data = currentState.getData(); - if (currentState.pop() == null) { + data = state.getData(); + if (state.pop() == null) { break; } breakOutList.add(0, data); //Insert because of stack-popping @@ -825,23 +608,23 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { /** {@inheritDoc} */ public void saveGraphicsState() { - currentState.push(); + state.push(); } /** {@inheritDoc} */ public void restoreGraphicsState() { - currentState.pop(); + state.pop(); } /** Indicates the beginning of a text object. */ public void beginTextObject() { - //TODO maybe? + //TODO PDF specific maybe? log.debug("NYI beginTextObject()"); } /** Indicates the end of a text object. */ public void endTextObject() { - //TODO maybe? + //TODO PDF specific maybe? log.debug("NYI endTextObject()"); } @@ -857,7 +640,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { String name = getInternalFontNameForArea(text); int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue(); - currentState.setFontSize(fontSize); + state.setFontSize(fontSize); AFPFont font = (AFPFont)fontInfo.getFonts().get(name); // Set letterSpacing @@ -867,10 +650,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { AFPFontAttributes afpFontAttributes = new AFPFontAttributes(name, font, fontSize); - AFPPageFonts pageFonts = currentState.getPageFonts(); + AFPPageFonts pageFonts = state.getPageFonts(); if (!pageFonts.containsKey(afpFontAttributes.getFontKey())) { // Font not found on current page, so add the new one - afpFontAttributes.setFontReference(currentState.incrementPageFontCount()); + afpFontAttributes.setFontReference(state.incrementPageFontCount()); pageFonts.put(afpFontAttributes.getFontKey(), afpFontAttributes); } else { // Use the previously stored font attributes @@ -904,16 +687,18 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { int x = (currentIPPosition + text.getBorderAndPaddingWidthStart()); int y = (currentBPPosition + text.getOffset() + text.getBaselineOffset()); float[] srcPts = new float[] {x, y}; - int[] coords = mpts2units(srcPts); + int[] coords = unitConv.mpts2units(srcPts); Color color = (Color) text.getTrait(Trait.COLOR); int variableSpaceCharacterIncrement = font.getWidth(' ', fontSize) / 1000 + text.getTextWordSpaceAdjust() + text.getTextLetterSpaceAdjust(); - variableSpaceCharacterIncrement = Math.round(mpt2units(variableSpaceCharacterIncrement)); + variableSpaceCharacterIncrement + = Math.round(unitConv.mpt2units(variableSpaceCharacterIncrement)); - int interCharacterAdjustment = Math.round(mpt2units(text.getTextLetterSpaceAdjust())); + int interCharacterAdjustment + = Math.round(unitConv.mpt2units(text.getTextLetterSpaceAdjust())); TextDataInfo textDataInfo = new TextDataInfo(); textDataInfo.setFontReference(fontReference); @@ -923,14 +708,15 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { textDataInfo.setVariableSpaceCharacterIncrement(variableSpaceCharacterIncrement); textDataInfo.setInterCharacterAdjustment(interCharacterAdjustment); textDataInfo.setData(data); - textDataInfo.setOrientation(currentState.getOrientation()); - getAFPDataStream().createText(textDataInfo); + textDataInfo.setOrientation(state.getOrientation()); + dataStream.createText(textDataInfo); // 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); + //TODO fix text decoration renderTextDecoration(font, fontSize, text, coords[Y], coords[X]); } @@ -970,28 +756,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** - * 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) { - currentState.setPortraitRotation(rotation); - } - - /** - * 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) { - currentState.setLandscapeRotation(rotation); - } - - /** * Get the MIME type of the renderer. * * @return The MIME type of the renderer @@ -1001,18 +765,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** - * Returns the page segments map - * - * @return the page segments map - */ - private Map/*<String,String>*/getPageSegments() { - if (pageSegmentsMap == null) { - pageSegmentsMap = new java.util.HashMap/*<String,String>*/(); - } - return pageSegmentsMap; - } - - /** * Method to render the page extension. * <p> * @@ -1020,7 +772,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the page object */ private void renderPageObjectExtensions(PageViewport pageViewport) { - this.pageSegmentsMap = null; + pageSegmentMap.clear(); if (pageViewport.getExtensionAttachments() != null && pageViewport.getExtensionAttachments().size() > 0) { // Extract all AFPPageSetup instances from the attachment list on @@ -1034,23 +786,22 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) { String overlay = aps.getName(); if (overlay != null) { - getAFPDataStream() - .createIncludePageOverlay(overlay); + dataStream.createIncludePageOverlay(overlay); } } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT .equals(element)) { String name = aps.getName(); String source = aps.getValue(); - getPageSegments().put(source, name); + pageSegmentMap.put(source, name); } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT .equals(element)) { String name = aps.getName(); String value = aps.getValue(); - getAFPDataStream().createTagLogicalElement(name, value); + dataStream.createTagLogicalElement(name, value); } else if (AFPElementMapping.NO_OPERATION.equals(element)) { String content = aps.getContent(); if (content != null) { - getAFPDataStream().createNoOperation(content); + dataStream.createNoOperation(content); } } } @@ -1060,13 +811,35 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { } /** + * 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) { + state.setPortraitRotation(rotation); + } + + /** + * 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) { + state.setLandscapeRotation(rotation); + } + + /** * Sets the number of bits used per pixel * * @param bitsPerPixel * number of bits per pixel */ public void setBitsPerPixel(int bitsPerPixel) { - currentState.setBitsPerPixel(bitsPerPixel); + state.setBitsPerPixel(bitsPerPixel); } /** @@ -1076,7 +849,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * color image output */ public void setColorImages(boolean colorImages) { - currentState.setColorImages(colorImages); + state.setColorImages(colorImages); } /** @@ -1084,11 +857,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * * @return the AFPDataStream */ - public AFPDataStream getAFPDataStream() { - if (afpDataStream == null) { - this.afpDataStream = new AFPDataStream(); - } - return afpDataStream; + public DataStream getAFPDocumentStream() { + return this.dataStream; } /** @@ -1098,7 +868,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * the output resolution (dpi) */ public void setResolution(int resolution) { - ((AFPState)getState()).setResolution(resolution); + state.setResolution(resolution); } /** @@ -1107,19 +877,16 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { * @return the resolution in dpi */ public int getResolution() { - return ((AFPState)getState()).getResolution(); + return state.getResolution(); } /** * Returns the current AFP state - * + * * @return the current AFP state */ - protected AbstractState getState() { - if (currentState == null) { - currentState = new AFPState(); - } - return currentState; + public AbstractState getState() { + return this.state; } // TODO: remove this and use the superclass implementation @@ -1158,25 +925,12 @@ public class AFPRenderer extends AbstractPathOrientedRenderer { currentBPPosition = saveBP; } - protected int[] transformPoints(float[] srcPts, float[] dstPts) { - return transformPoints(srcPts, dstPts, true); - } - - protected int[] transformPoints(float[] srcPts, float[] dstPts, boolean milli) { - if (dstPts == null) { - dstPts = new float[srcPts.length]; - } - AbstractState state = (AbstractState)getState(); - AffineTransform at = state.getData().getTransform(); - at.transform(srcPts, 0, dstPts, 0, srcPts.length / 2); - int[] coords = new int[srcPts.length]; - for (int i = 0; i < srcPts.length; i++) { - if (!milli) { - dstPts[i] *= 1000; - } - coords[i] = Math.round(dstPts[i]); - } - return coords; + /** + * Sets the default resource group file path + * @param filePath the default resource group file path + */ + public void setDefaultResourceGroupFilePath(String filePath) { + resourceManager.setDefaultResourceGroupFilePath(filePath); } } diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java index f688896ab..95a210ce5 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java @@ -36,7 +36,6 @@ 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.render.afp.modca.AFPDataStream; import org.apache.fop.util.LogUtil; /** @@ -260,8 +259,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator { } File resourceGroupFile = new File(resourceGroupDest); if (resourceGroupFile.canWrite()) { - AFPDataStream datastream = afpRenderer.getAFPDataStream(); - datastream.setDefaultResourceGroupFilePath(resourceGroupDest); + 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/AFPRendererContextConstants.java b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java index d12c5f2c3..72be26483 100644 --- a/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java +++ b/src/java/org/apache/fop/render/afp/AFPRendererContextConstants.java @@ -35,8 +35,8 @@ public interface AFPRendererContextConstants extends RendererContextConstants { /** The font information for the AFP renderer. */ String AFP_FONT_INFO = "afpFontInfo"; - /** The afp datastream */ - String AFP_DATASTREAM = "afpDataStream"; + /** The afp resource manager */ + String AFP_RESOURCE_MANAGER = "afpResourceManager"; /** The afp state */ String AFP_STATE = "afpPageState"; diff --git a/src/java/org/apache/fop/render/afp/ResourceInfo.java b/src/java/org/apache/fop/render/afp/AFPResourceInfo.java index 67f03bfd2..fd9ae23e5 100644 --- a/src/java/org/apache/fop/render/afp/ResourceInfo.java +++ b/src/java/org/apache/fop/render/afp/AFPResourceInfo.java @@ -5,9 +5,9 @@ * 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. @@ -22,28 +22,31 @@ package org.apache.fop.render.afp; /** * The level at which a resource is to reside in the AFP output */ -public class ResourceInfo { +public class AFPResourceInfo { + private static final AFPResourceLevel DEFAULT_LEVEL + = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE); + /** the uri of this resource */ private String uri; - + /** the reference name of this resource */ private String name = null; - - /** the resource level (default to print-file) */ - private ResourceLevel level = new ResourceLevel(ResourceLevel.PRINT_FILE); - + + /** the resource levek of this resource */ + private AFPResourceLevel level = null; + /** * Sets the data object uri - * + * * @param uri the data object uri */ public void setUri(String uri) { this.uri = uri; } - + /** * Returns the uri of this data object - * + * * @return the uri of this data object */ public String getUri() { @@ -52,62 +55,65 @@ public class ResourceInfo { /** * Sets the resource reference name - * + * * @param resourceName the resource reference name */ public void setName(String resourceName) { this.name = resourceName; - } + } /** * Returns the resource reference name - * + * * @return the resource reference name */ public String getName() { return this.name; } - + /** * Returns the resource level - * + * * @return the resource level */ - public ResourceLevel getLevel() { + public AFPResourceLevel getLevel() { + if (level == null) { + return DEFAULT_LEVEL; + } return this.level; } /** * Sets the resource level - * + * * @param resourceLevel the resource level */ - public void setLevel(ResourceLevel resourceLevel) { + public void setLevel(AFPResourceLevel resourceLevel) { this.level = resourceLevel; } /** {@inheritDoc} */ public String toString() { - return "ResourceInfo(uri=" + uri + return "AFPResourceInfo(uri=" + uri + (name != null ? ", name=" + name : "") + (level != null ? ", level=" + level : "") + ")"; } - + /** {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) { return true; } - if ((obj == null) || !(obj instanceof ResourceInfo)) { + if ((obj == null) || !(obj instanceof AFPResourceInfo)) { return false; } - ResourceInfo ri = (ResourceInfo)obj; + AFPResourceInfo ri = (AFPResourceInfo)obj; return (uri == ri.uri || uri != null && uri.equals(ri.uri)) && (name == ri.name || name != null && name.equals(ri.name)) && (level == ri.level || level != null && level.equals(ri.level)); } - + /** {@inheritDoc} */ public int hashCode() { int hash = 7; diff --git a/src/java/org/apache/fop/render/afp/ResourceLevel.java b/src/java/org/apache/fop/render/afp/AFPResourceLevel.java index 205a483ff..a7c6bf44b 100644 --- a/src/java/org/apache/fop/render/afp/ResourceLevel.java +++ b/src/java/org/apache/fop/render/afp/AFPResourceLevel.java @@ -5,9 +5,9 @@ * 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. @@ -22,8 +22,8 @@ package org.apache.fop.render.afp; /** * A resource level */ -public class ResourceLevel { - +public class AFPResourceLevel { + /** page level **/ public static final int PAGE = 0; @@ -38,7 +38,7 @@ public class ResourceLevel { /** external level **/ public static final int EXTERNAL = 4; - + private static final String NAME_PAGE = "page"; private static final String NAME_PAGE_GROUP = "page-group"; private static final String NAME_DOCUMENT = "document"; @@ -48,8 +48,8 @@ public class ResourceLevel { private static final String[] NAMES = new String[] {NAME_PAGE, NAME_PAGE_GROUP, NAME_DOCUMENT, NAME_PRINT_FILE, NAME_EXTERNAL}; - - + + /** where the resource will reside in the AFP output */ private int level = PRINT_FILE; // default is print-file level @@ -58,36 +58,37 @@ public class ResourceLevel { /** * Sets the resource placement level within the AFP output - * - * @param lvl the resource level (page, page-group, document, print-file or external) + * + * @param levelString the resource level (page, page-group, document, print-file or external) * @return true if the resource level was successfully set */ - public static ResourceLevel valueOf(String lvl) { - ResourceLevel level = null; - for (int i = 0; i < NAMES.length; i++) { - if (NAMES[i].equals(lvl)) { - level = new ResourceLevel(i); - break; + public static AFPResourceLevel valueOf(String levelString) { + if (levelString != null) { + levelString = levelString.toLowerCase(); + AFPResourceLevel resourceLevel = null; + for (int i = 0; i < NAMES.length; i++) { + if (NAMES[i].equals(levelString)) { + resourceLevel = new AFPResourceLevel(i); + break; + } } + return resourceLevel; } - if (lvl == null) { - throw new IllegalArgumentException("Unknown resource level '" + lvl + "'"); - } - return level; + return null; } - + /** * Main constructor - * + * * @param level the resource level */ - public ResourceLevel(int level) { + public AFPResourceLevel(int level) { setLevel(level); } /** * Sets the resource level - * + * * @param level the resource level */ public void setLevel(int level) { @@ -95,53 +96,62 @@ public class ResourceLevel { } /** - * Returns true if this is a page level resource group - * - * @return true if this is a page level resource group + * Returns true if this is a page level + * + * @return true if this is a page level */ public boolean isPage() { return level == PAGE; } - + /** - * Returns true if this is a page group level resource group - * - * @return true if this is a page group level resource group + * Returns true if this is page group level + * + * @return true if this is page group level */ public boolean isPageGroup() { return level == PAGE_GROUP; } /** - * Returns true if this is a document level resource group - * - * @return true if this is a document level resource group + * Returns true if this is document level + * + * @return true if this is document level */ public boolean isDocument() { return level == DOCUMENT; } /** - * Returns true if this is an external level resource group - * - * @return true if this is an external level resource group + * Returns true if this is external level + * + * @return true if this is external level */ public boolean isExternal() { return level == EXTERNAL; } /** - * Returns true if this is a print-file level resource group - * - * @return true if this is a print-file level resource group + * Returns true if this is print-file level + * + * @return true if this is print-file level */ public boolean isPrintFile() { return level == PRINT_FILE; } - + + /** + * Returns true if this resource level is inlined + * + * @return true if this resource level is inlined + */ + public boolean isInlined() { + return isPage() || isPageGroup() || isDocument(); + } + /** * Returns the destination file path of the external resource group file - * + * * @return the destination file path of the external resource group file */ public String getExternalFilePath() { @@ -150,7 +160,7 @@ public class ResourceLevel { /** * Sets the external destination of the resource - * + * * @param filePath the external resource group file */ public void setExternalFilePath(String filePath) { @@ -161,22 +171,22 @@ public class ResourceLevel { public String toString() { return NAMES[level] + (isExternal() ? ", file=" + extFilePath : ""); } - + /** {@inheritDoc} */ public boolean equals(Object obj) { if (this == obj) { return true; } - if ((obj == null) || !(obj instanceof ResourceLevel)) { + if ((obj == null) || !(obj instanceof AFPResourceLevel)) { return false; } - ResourceLevel rl = (ResourceLevel)obj; + AFPResourceLevel rl = (AFPResourceLevel)obj; return (level == level) && (extFilePath == rl.extFilePath || extFilePath != null && extFilePath.equals(rl.extFilePath)); } - + /** {@inheritDoc} */ public int hashCode() { int hash = 7; diff --git a/src/java/org/apache/fop/render/afp/AFPResourceManager.java b/src/java/org/apache/fop/render/afp/AFPResourceManager.java new file mode 100644 index 000000000..f8138b732 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPResourceManager.java @@ -0,0 +1,184 @@ +/* + * 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.OutputStream; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.afp.modca.AbstractDataObject; +import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; +import org.apache.fop.render.afp.modca.DataStream; +import org.apache.fop.render.afp.modca.Factory; +import org.apache.fop.render.afp.modca.ImageObject; +import org.apache.fop.render.afp.modca.IncludeObject; +import org.apache.fop.render.afp.modca.Registry; +import org.apache.fop.render.afp.modca.ResourceGroup; + +/** + * Manages the creation and storage of document resources + */ +public class AFPResourceManager { + /** Static logging instance */ + private static final Log log = LogFactory.getLog(AFPResourceManager.class); + + /** The AFP datastream (document tree) */ + private DataStream dataStream; + + /** Resource creation factory */ + private final Factory factory; + + private final AFPStreamer streamer; + + private final AFPDataObjectFactory dataObjectFactory; + + /** Maintain a reference count of instream objects for referencing purposes */ + private int instreamObjectCount = 0; + + /** a mapping of resourceInfo --> include name */ + private final Map/*<ResourceInfo,String>*/ includeNameMap + = new java.util.HashMap()/*<ResourceInfo,String>*/; + + /** + * Main constructor + */ + public AFPResourceManager() { + this.factory = new Factory(); + this.streamer = new AFPStreamer(factory); + this.dataObjectFactory = new AFPDataObjectFactory(factory); + } + + /** + * Sets the outputstream + * + * @param outputStream the outputstream + */ + public void setOutputStream(OutputStream outputStream) { + this.dataStream = streamer.createDataStream(); + streamer.setOutputStream(outputStream); + } + + /** + * Returns the AFPDocumentStream + * + * @return the AFPDocumentStream + */ + public DataStream getDataStream() { + return this.dataStream; + } + + /** + * Tells the streamer to write + * + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + public void writeToStream() throws IOException { + streamer.close(); + } + + /** + * Sets the default resource group file path + * + * @param filePath the default resource group file path + */ + + public void setDefaultResourceGroupFilePath(String filePath) { + streamer.setDefaultResourceGroupFilePath(filePath); + } + + /** + * Creates and returns a new data object + * + * @param dataObjectInfo the data object info + * + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + public void createObject(AFPDataObjectInfo dataObjectInfo) throws IOException { + AbstractNamedAFPObject namedObj = null; + + AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); + String uri = resourceInfo.getUri(); + if (uri == null) { + uri = "/"; + } + // if this is an instream data object adjust uri to ensure that it is + // unique + if (uri.endsWith("/")) { + uri += "#" + (++instreamObjectCount); + resourceInfo.setUri(uri); + } + + // try and find an include name for the same resource + String includeName = (String)includeNameMap.get(resourceInfo); + if (includeName == null) { + + // new resource so create + if (dataObjectInfo instanceof AFPImageObjectInfo) { + namedObj = dataObjectFactory.createImage((AFPImageObjectInfo)dataObjectInfo); + } else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) { + namedObj = dataObjectFactory.createGraphic((AFPGraphicsObjectInfo)dataObjectInfo); + } else { + throw new IllegalArgumentException("Unknown data object type: " + dataObjectInfo); + } + + if (namedObj instanceof AbstractDataObject) { + AbstractDataObject dataObj = (AbstractDataObject)namedObj; + dataObj.setViewport(dataObjectInfo); + } + + AFPResourceLevel resourceLevel = resourceInfo.getLevel(); + + Registry.ObjectType objectType = dataObjectInfo.getObjectType(); + boolean canInclude = (namedObj instanceof ImageObject + || objectType != null && objectType.isIncludable()); + if (canInclude) { + // if it is to reside within a resource group at print-file or external level + if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) { + // wrap newly created data object in a resource object + namedObj = dataObjectFactory.createResource(namedObj, resourceInfo, objectType); + } + + // add data object into its resource group destination + ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel); + resourceGroup.addObject(namedObj); + + // add an include to the current page + includeName = namedObj.getName(); + IncludeObject includeObject + = dataObjectFactory.createInclude(includeName, dataObjectInfo); + dataStream.getCurrentPage().addObject(includeObject); + + // record name of data object for the resource + includeNameMap.put(resourceInfo, namedObj.getName()); + } else { + // add data object directly into the current page + dataStream.getCurrentPage().addObject(namedObj); + } + } else { + // existing resource so reference by adding an include to the current page + IncludeObject includeObject + = dataObjectFactory.createInclude(includeName, dataObjectInfo); + dataStream.getCurrentPage().addObject(includeObject); + } + } + +} diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java index 45588952a..8ea7467e5 100644 --- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java @@ -37,7 +37,6 @@ 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.render.afp.modca.AFPDataStream; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; import org.apache.xmlgraphics.util.QName; @@ -50,8 +49,12 @@ import org.w3c.dom.Document; */ public class AFPSVGHandler extends AbstractGenericSVGHandler { + /** foreign attribute reader */ + private final AFPForeignAttributeReader foreignAttributeReader + = new AFPForeignAttributeReader(); + /** {@inheritDoc} */ - public void handleXML(RendererContext context, + public void handleXML(RendererContext context, Document doc, String ns) throws Exception { if (SVGDOMImplementation.SVG_NAMESPACE_URI.equals(ns)) { renderSVGDocument(context, doc); @@ -75,21 +78,21 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { AFPRendererContextConstants.AFP_FONT_INFO)); afpi.setState((AFPState)context.getProperty( AFPRendererContextConstants.AFP_STATE)); - afpi.setAFPDataStream((AFPDataStream)context.getProperty( - AFPRendererContextConstants.AFP_DATASTREAM)); + afpi.setResourceManager(((AFPResourceManager)context.getProperty( + AFPRendererContextConstants.AFP_RESOURCE_MANAGER))); Map foreign = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES); QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); - if (foreign != null + if (foreign != null && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) { - afpi.paintAsBitmap = true; + afpi.setPaintAsBitmap(true); } return afpi; } - + /** * 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 @@ -99,7 +102,9 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { AFPRenderer renderer = (AFPRenderer)context.getRenderer(); AFPInfo afpInfo = getAFPInfo(context); - if (afpInfo.paintAsBitmap) { + + // fallback paint as bitmap + if (afpInfo.paintAsBitmap()) { try { super.renderSVGDocument(context, doc); } catch (IOException ioe) { @@ -111,31 +116,52 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { } String uri = ((AbstractDocument)doc).getDocumentURI(); - AFPState currentState = (AFPState)renderer.getState(); - currentState.setImageUri(uri); - - // set the data object parameters - ObjectAreaInfo objectAreaInfo = new ObjectAreaInfo(); - - int x = (int)Math.round((afpInfo.getX() * 25.4f) / 1000f); - objectAreaInfo.setX(x); - - int y = (int)Math.round((afpInfo.getY() * 25.4f) / 1000f); - objectAreaInfo.setY(y); + AFPState state = (AFPState)renderer.getState(); + state.setImageUri(uri); + + // set the data object parameters + AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo(); + + AFPUnitConverter unitConv = state.getUnitConverter(); + +// RendererContextWrapper rctx = RendererContext.wrapRendererContext(context); +// int currx = rctx.getCurrentXPosition(); +// int curry = rctx.getCurrentYPosition(); +// int afpx = Math.round(unitConv.mpt2units(currx)); +// int afpy = Math.round(unitConv.mpt2units(curry)); +// objectAreaInfo.setOffsetX(afpx); +// objectAreaInfo.setOffsetY(afpy); + + AffineTransform at = state.getData().getTransform(); + float transX = (float)at.getTranslateX(); + float transY = (float)at.getTranslateY(); +// int afpx = Math.round(unitConv.mpt2units(currx)); +// objectAreaInfo.setX(afpx); +// int afpy = Math.round(unitConv.mpt2units(curry)); +// objectAreaInfo.setY(afpy); +// objectAreaInfo.setX(coords[0]); +// objectAreaInfo.setY(coords[1]); + objectAreaInfo.setX(Math.round(transX)); + objectAreaInfo.setY(Math.round(transY)); + +// AffineTransform at = currentState.getData().getTransform(); +// int x = (int)Math.round(at.getTranslateX()); +// objectAreaInfo.setX(x); +// +// int y = (int)Math.round(at.getTranslateY()); +// objectAreaInfo.setY(y); int resolution = afpInfo.getResolution(); objectAreaInfo.setWidthRes(resolution); objectAreaInfo.setHeightRes(resolution); - int width = (int)Math.round((afpInfo.getWidth() * resolution) - / AFPConstants.DPI_72_MPTS); + int width = Math.round(unitConv.mpt2units(afpInfo.getWidth())); objectAreaInfo.setWidth(width); - int height = (int)Math.round((afpInfo.getHeight() * resolution) - / AFPConstants.DPI_72_MPTS); + int height = Math.round(unitConv.mpt2units(afpInfo.getHeight())); objectAreaInfo.setHeight(height); - DataObjectInfo dataObjectInfo = new GraphicsObjectInfo(); + AFPDataObjectInfo dataObjectInfo = new AFPGraphicsObjectInfo(); dataObjectInfo.setUri(uri); // Configure Graphics2D implementation @@ -143,11 +169,10 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { AFPGraphics2D graphics = new AFPGraphics2D(textAsShapes); graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext()); graphics.setAFPInfo(afpInfo); - + // Configure GraphicsObjectPainter with the Graphics2D implementation - GraphicsObjectPainter painter = new GraphicsObjectPainter(); - painter.setGraphics2D(graphics); - ((GraphicsObjectInfo)dataObjectInfo).setPainter(painter); + AFPGraphicsObjectPainter painter = new AFPGraphicsObjectPainter(graphics); + ((AFPGraphicsObjectInfo)dataObjectInfo).setPainter(painter); boolean strokeText = false; Configuration cfg = afpInfo.getHandlerConfiguration(); @@ -156,25 +181,26 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { } SVGUserAgent svgUserAgent = new SVGUserAgent(context.getUserAgent(), new AffineTransform()); - + BridgeContext ctx = new BridgeContext(svgUserAgent); AFPTextHandler afpTextHandler = null; - + //Controls whether text painted by Batik is generated using text or path operations if (!strokeText) { afpTextHandler = new AFPTextHandler(graphics); graphics.setCustomTextHandler(afpTextHandler); AFPTextPainter textPainter = new AFPTextPainter(afpTextHandler); - ctx.setTextPainter(textPainter); + ctx.setTextPainter(textPainter); AFPTextElementBridge tBridge = new AFPTextElementBridge(textPainter); ctx.putBridge(tBridge); } - + Map/*<QName, String>*/ foreignAttributes = (Map/*<QName, String>*/)context.getProperty( RendererContextConstants.FOREIGN_ATTRIBUTES); - dataObjectInfo.setResourceInfoFromForeignAttributes(foreignAttributes); - + AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes); + dataObjectInfo.setResourceInfo(resourceInfo); + // Build the SVG DOM and provide the painter with it GraphicsNode root; GVTBuilder builder = new GVTBuilder(); @@ -187,18 +213,18 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { eventProducer.svgNotBuilt(this, e, uri); return; } - + + // convert to afp inches Dimension2D dim = ctx.getDocumentSize(); double w = dim.getWidth() * 1000f; double h = dim.getHeight() * 1000f; - - // convert to afp inches - double scaleX = ((afpInfo.getWidth() / w) * resolution) / AFPConstants.DPI_72; - double scaleY = ((afpInfo.getHeight() / h) * resolution) / AFPConstants.DPI_72; - double xOffset = (afpInfo.getX() * resolution) / AFPConstants.DPI_72_MPTS; - double yOffset - = ((afpInfo.getHeight() - afpInfo.getY()) * resolution) / AFPConstants.DPI_72_MPTS; - + double wx = (afpInfo.getWidth() / w); + double hx = (afpInfo.getHeight() / h); + double scaleX = unitConv.pt2units((float)wx); + double scaleY = unitConv.pt2units((float)hx); + double xOffset = unitConv.mpt2units(afpInfo.getX()); + double yOffset = unitConv.mpt2units(afpInfo.getHeight()); + // Transformation matrix that establishes the local coordinate system // for the SVG graphic in relation to the current coordinate system // (note: y axis is inverted) @@ -208,10 +234,12 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { // Set the object area info dataObjectInfo.setObjectAreaInfo(objectAreaInfo); - // Create the object - afpInfo.getAFPDataStream().createObject(dataObjectInfo); + AFPResourceManager resourceManager = afpInfo.getAFPResourceManager(); + + // Create the graphics object + resourceManager.createObject(dataObjectInfo); } - + /** {@inheritDoc} */ public boolean supportsRenderer(Renderer renderer) { return (renderer instanceof AFPRenderer); @@ -222,4 +250,5 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler { //Work around a problem in Batik: Gradients cannot be done in ColorSpace.CS_GRAY context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE, Boolean.FALSE); } + } diff --git a/src/java/org/apache/fop/render/afp/AFPState.java b/src/java/org/apache/fop/render/afp/AFPState.java index 8c8aaba14..129222b6a 100644 --- a/src/java/org/apache/fop/render/afp/AFPState.java +++ b/src/java/org/apache/fop/render/afp/AFPState.java @@ -23,11 +23,14 @@ import java.awt.geom.AffineTransform; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.AbstractState; /** * This keeps information about the current state when writing to an AFP datastream. */ -public class AFPState extends org.apache.fop.render.AbstractState { +public class AFPState extends org.apache.fop.render.AbstractState implements Cloneable { + + private static final long serialVersionUID = 8206711712452344473L; private static Log log = LogFactory.getLog("org.apache.fop.render.afp.AFPState"); @@ -38,7 +41,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { private int landscapeRotation = 270; /** Flag to the set the output object type for images */ - private boolean colorImages = false; + private boolean colorImages = true; /** Default value for image depth */ private int bitsPerPixel = 8; @@ -49,6 +52,9 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** The current page */ private AFPPageState pageState = new AFPPageState(); + /** A unit converter */ + private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this); + /** * Sets the rotation to be used for portrait pages, valid values are 0 * (default), 90, 180, 270. @@ -70,7 +76,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the rotation to be used for portrait pages - * + * * @return the rotation to be used for portrait pages */ protected int getPortraitRotation() { @@ -97,7 +103,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the landscape rotation - * + * * @return the landscape rotation */ protected int getLandscapeRotation() { @@ -126,7 +132,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the number of bits per pixel - * + * * @return the number of bits per pixel */ public int getBitsPerPixel() { @@ -145,7 +151,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns true if color images are to be used - * + * * @return true if color images are to be used */ protected boolean isColorImages() { @@ -179,9 +185,14 @@ public class AFPState extends org.apache.fop.render.AbstractState { return new AFPData(); } + /** {@inheritDoc} */ + protected AbstractState instantiateState() { + return new AFPState(); + } + /** * Returns the state of the current page - * + * * @return the state of the current page */ protected AFPPageState getPageState() { @@ -190,7 +201,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets if the current painted shape is to be filled - * + * * @param fill true if the current painted shape is to be filled * @return true if the fill value has changed */ @@ -204,7 +215,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Gets the current page fonts - * + * * @return the current page fonts */ protected AFPPageFonts getPageFonts() { @@ -213,7 +224,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Increments and returns the page font count - * + * * @return the page font count */ public int incrementPageFontCount() { @@ -222,7 +233,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the page width - * + * * @param pageWidth the page width */ public void setPageWidth(int pageWidth) { @@ -231,7 +242,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the page width - * + * * @return the page width */ public int getPageWidth() { @@ -240,7 +251,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the page height - * + * * @param pageHeight the page height */ public void setPageHeight(int pageHeight) { @@ -249,7 +260,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the page height - * + * * @return the page height */ public int getPageHeight() { @@ -258,7 +269,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the uri of the current image - * + * * @param uri the uri of the current image */ protected void setImageUri(String uri) { @@ -267,7 +278,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Gets the uri of the current image - * + * * @return the uri of the current image */ public String getImageUri() { @@ -276,7 +287,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the current orientation - * + * * @return the current orientation */ public int getOrientation() { @@ -295,21 +306,43 @@ public class AFPState extends org.apache.fop.render.AbstractState { return orientation; } + /** + * Returns the unit converter + * + * @return the unit converter + */ + public AFPUnitConverter getUnitConverter() { + return this.unitConv; + } + + /** {@inheritDoc} */ + public Object clone() { + AFPState state = (AFPState)super.clone(); + state.pageState = (AFPPageState)this.pageState.clone(); + state.portraitRotation = this.portraitRotation; + state.landscapeRotation = this.landscapeRotation; + state.bitsPerPixel = this.bitsPerPixel; + state.colorImages = this.colorImages; + state.resolution = this.resolution; + return state; + } + /** {@inheritDoc} */ public String toString() { - return "AFPState{portraitRotation=" + portraitRotation + return "AFPState{" + "portraitRotation=" + portraitRotation + ", landscapeRotation=" + landscapeRotation + ", colorImages=" + colorImages + ", bitsPerPixel=" + bitsPerPixel + ", resolution=" + resolution + ", pageState=" + pageState + + super.toString() + "}"; } /** * Page level state data */ - private class AFPPageState { + private class AFPPageState implements Cloneable { /** The current page width */ private int width = 0; @@ -324,7 +357,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the page width - * + * * @return the page width */ protected int getWidth() { @@ -333,7 +366,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the page width - * + * * @param width the page width */ protected void setWidth(int width) { @@ -342,7 +375,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the page height - * + * * @return the page height */ protected int getHeight() { @@ -351,7 +384,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the page height - * + * * @param height the page height */ protected void setHeight(int height) { @@ -360,7 +393,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Returns the page fonts - * + * * @return the page fonts */ protected AFPPageFonts getFonts() { @@ -369,7 +402,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Sets the current page fonts - * + * * @param fonts the current page fonts */ protected void setFonts(AFPPageFonts fonts) { @@ -378,7 +411,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { /** * Increments and returns the current page font count - * + * * @return increment and return the current page font count */ protected int incrementFontCount() { @@ -386,6 +419,16 @@ public class AFPState extends org.apache.fop.render.AbstractState { } /** {@inheritDoc} */ + public Object clone() { + AFPPageState state = new AFPPageState(); + state.fonts = new AFPPageFonts(this.fonts); + state.height = this.height; + state.width = this.width; + state.fontCount = this.fontCount; + return state; + } + + /** {@inheritDoc} */ public String toString() { return "AFPPageState{width=" + width + ", height=" + height @@ -396,7 +439,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { } /** - * Block level data + * Block level state data */ private class AFPData extends org.apache.fop.render.AbstractState.AbstractData { private static final long serialVersionUID = -1789481244175275686L; @@ -407,7 +450,7 @@ public class AFPState extends org.apache.fop.render.AbstractState { private String imageUri = null; /** {@inheritDoc} */ - public Object clone() throws CloneNotSupportedException { + public Object clone() { AFPData obj = (AFPData)super.clone(); obj.filled = this.filled; obj.imageUri = this.imageUri; diff --git a/src/java/org/apache/fop/render/afp/AFPStreamer.java b/src/java/org/apache/fop/render/afp/AFPStreamer.java new file mode 100644 index 000000000..ac8149dcf --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPStreamer.java @@ -0,0 +1,214 @@ +/* + * 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.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.afp.modca.DataStream; +import org.apache.fop.render.afp.modca.Factory; +import org.apache.fop.render.afp.modca.ResourceGroup; +import org.apache.fop.render.afp.modca.StreamedResourceGroup; +import org.apache.fop.util.store.Streamable; + +/** + * Manages the streaming of the AFP output + */ +public class AFPStreamer implements Streamable { + /** Static logging instance */ + private static final Log log = LogFactory.getLog(AFPStreamer.class); + + private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_"; + + private static final int BUFFER_SIZE = 4096; + + private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp"; + + + private final Factory factory; + + /** A mapping of external resource destinations to resource groups */ + private final Map/*<String,AFPExternalResourceGroup>*/pathResourceGroupMap + = new java.util.HashMap/*<String,AFPExternalResourceGroup>*/(); + + private StreamedResourceGroup printFileResourceGroup; + + /** Sets the default resource group file path */ + private String defaultResourceGroupFilePath = DEFAULT_EXTERNAL_RESOURCE_FILENAME; + + private File tempFile; + + /** temporary document outputstream */ + private OutputStream documentOutputStream; + + /** the final outputstream */ + private OutputStream outputStream; + + private RandomAccessFile documentFile; + + private DataStream dataStream; + + /** + * Main constructor + * + * @param factory a factory + */ + public AFPStreamer(Factory factory) { + this.factory = factory; + } + + /** + * Creates a new DataStream + * + * @return a new {@link DataStream} + */ + public DataStream createDataStream() { + try { + this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null); + this.documentFile = new RandomAccessFile(tempFile, "rw"); + this.documentOutputStream = new BufferedOutputStream( + new FileOutputStream(documentFile.getFD())); + this.dataStream = factory.createDataStream(documentOutputStream); + } catch (IOException e) { + log.error(e.getMessage()); + } + return dataStream; + } + + /** + * Sets the default resource group file path + * + * @param filePath the default resource group file path + */ + public void setDefaultResourceGroupFilePath(String filePath) { + this.defaultResourceGroupFilePath = filePath; + } + + /** + * Returns the resource group for a given resource info + * + * @param level a resource level + * @return a resource group for the given resource info + */ + public ResourceGroup getResourceGroup(AFPResourceLevel level) { + ResourceGroup resourceGroup = null; + if (level.isExternal()) { + String filePath = level.getExternalFilePath(); + if (filePath == null) { + log.warn("No file path provided for external resource, using default."); + filePath = defaultResourceGroupFilePath; + } + resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath); + if (resourceGroup == null) { + OutputStream os = null; + try { + os = new BufferedOutputStream(new FileOutputStream(filePath)); + } catch (FileNotFoundException fnfe) { + log.error("Failed to create/open external resource group file '" + + filePath + "'"); + } finally { + if (os != null) { + resourceGroup = factory.createStreamedResourceGroup(os); + pathResourceGroupMap.put(filePath, resourceGroup); + } + } + } + } else if (level.isPrintFile()) { + if (printFileResourceGroup == null) { + // use final outputstream for print-file resource group + printFileResourceGroup = factory.createStreamedResourceGroup(outputStream); + } + resourceGroup = printFileResourceGroup; + } else { + // resource group in afp document datastream + resourceGroup = dataStream.getResourceGroup(level); + } + return resourceGroup; + } + + /** + * Closes off the AFP stream writing the document stream + * + * @throws IOException if an an I/O exception of some sort has occurred + */ + public void close() throws IOException { + // write out any external resource groups + Iterator it = pathResourceGroupMap.entrySet().iterator(); + while (it.hasNext()) { + StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next(); + resourceGroup.close(); + } + + // close any open print-file resource group + if (printFileResourceGroup != null) { + printFileResourceGroup.close(); + } + + // write out document + writeToStream(outputStream); + + outputStream.close(); + + // delete temporary file + tempFile.delete(); + } + + /** + * Sets the final outputstream + * + * @param outputStream an outputstream + */ + public void setOutputStream(OutputStream outputStream) { + this.outputStream = outputStream; + } + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + int len = (int)documentFile.length(); + int numChunks = len / BUFFER_SIZE; + int remainingChunkSize = len % BUFFER_SIZE; + byte[] buffer; + + documentFile.seek(0); + if (numChunks > 0) { + buffer = new byte[BUFFER_SIZE]; + for (int i = 0; i < numChunks; i++) { + documentFile.read(buffer, 0, BUFFER_SIZE); + os.write(buffer, 0, BUFFER_SIZE); + } + } else { + buffer = new byte[remainingChunkSize]; + } + if (remainingChunkSize > 0) { + documentFile.read(buffer, 0, remainingChunkSize); + os.write(buffer, 0, remainingChunkSize); + } + os.flush(); + } +}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/AFPUnitConverter.java b/src/java/org/apache/fop/render/afp/AFPUnitConverter.java new file mode 100644 index 000000000..8a25bb604 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/AFPUnitConverter.java @@ -0,0 +1,120 @@ +/* + * 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.AffineTransform; + + +/** + * AFP Unit converter + */ +public class AFPUnitConverter { + + /** the AFP state */ + private final AFPState state; + + /** + * Unit converter + * + * @param state the AFP state + */ + public AFPUnitConverter(AFPState state) { + this.state = state; + } + + /** + * Converts millipoints to units + * + * @param srcPts source points + * @param dstPts destination points + * @return transformed points + */ + public int[] mpts2units(float[] srcPts, float[] dstPts) { + return transformPoints(srcPts, dstPts, true); + } + + /** + * Converts points to units + * + * @param srcPts source points + * @param dstPts destination points + * @return transformed points + */ + public int[] pts2units(float[] srcPts, float[] dstPts) { + return transformPoints(srcPts, dstPts, false); + } + + /** + * Converts millipoints to units + * + * @param srcPts source points + * @return transformed points + */ + public int[] mpts2units(float[] srcPts) { + return transformPoints(srcPts, null, true); + } + + /** + * Converts points to units + * + * @param srcPts source points + * @return transformed points + */ + public int[] pts2units(float[] srcPts) { + return transformPoints(srcPts, null, false); + } + + /** + * Converts point to unit + * + * @param pt point + * @return transformed point + */ + public float pt2units(float pt) { + return pt / ((float)AFPConstants.DPI_72 / state.getResolution()); + } + + /** + * Converts millipoint to unit + * + * @param mpt millipoint + * @return transformed point + */ + public float mpt2units(float mpt) { + return mpt / ((float)AFPConstants.DPI_72_MPTS / state.getResolution()); + } + + private int[] transformPoints(float[] srcPts, float[] dstPts, boolean milli) { + if (dstPts == null) { + dstPts = new float[srcPts.length]; + } + AffineTransform at = state.getData().getTransform(); + at.transform(srcPts, 0, dstPts, 0, srcPts.length / 2); + int[] coords = new int[srcPts.length]; + for (int i = 0; i < srcPts.length; i++) { + if (!milli) { + dstPts[i] *= 1000; + } + coords[i] = Math.round(dstPts[i]); + } + return coords; + } + +} diff --git a/src/java/org/apache/fop/render/afp/DataObjectInfo.java b/src/java/org/apache/fop/render/afp/DataObjectInfo.java deleted file mode 100644 index dc4d09c7f..000000000 --- a/src/java/org/apache/fop/render/afp/DataObjectInfo.java +++ /dev/null @@ -1,209 +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 java.io.File; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.afp.extensions.AFPElementMapping; -import org.apache.fop.render.afp.modca.Registry; -import org.apache.fop.render.afp.modca.Registry.ObjectType; -import org.apache.xmlgraphics.util.QName; - -/** - * A list of parameters associated with an AFP data objects - */ -public abstract class DataObjectInfo { - private static final Log log = LogFactory.getLog("org.apache.fop.afp"); - - private static final String RESOURCE_NAME = "afp:resource-name"; - private static final String RESOURCE_LEVEL = "afp:resource-level"; - private static final String RESOURCE_GROUP_FILE = "afp:resource-group-file"; - - /** the object area info */ - private ObjectAreaInfo objectAreaInfo; - - /** object type entry */ - private Registry.ObjectType objectType; - - /** resource info */ - private ResourceInfo resourceInfo; - - /** - * Default constructor - */ - public DataObjectInfo() { - } - - /** - * Sets the object type - * - * @param objectType the object type - */ - public void setObjectType(Registry.ObjectType objectType) { - this.objectType = objectType; - } - - /** - * Returns the object type MOD:CA Registry entry - * - * @return the object type MOD:CA Registry entry - */ - public ObjectType getObjectType() { - return objectType; - } - - /** - * Returns the resource level at which this data object should reside - * - * @return the resource level at which this data object should reside - */ - public ResourceInfo getResourceInfo() { - if (resourceInfo == null) { - this.resourceInfo = new ResourceInfo(); - } - return resourceInfo; - } - - /** - * Sets the resource level at which this object should reside - * - * @param resourceInfo the resource level at which this data object should reside - */ - public void setResourceInfo(ResourceInfo resourceInfo) { - this.resourceInfo = resourceInfo; - } - - /** - * Sets the object area info - * - * @param objectAreaInfo the object area info - */ - public void setObjectAreaInfo(ObjectAreaInfo objectAreaInfo) { - this.objectAreaInfo = objectAreaInfo; - } - - /** - * Returns the object area info - * - * @return the object area info - */ - public ObjectAreaInfo getObjectAreaInfo() { - return this.objectAreaInfo; - } - - /** - * Sets the resource group settings using the given foreign attributes - * - * @param foreignAttributes a mapping of element attributes names to values - */ - public void setResourceInfoFromForeignAttributes(Map/*<QName, String>*/ foreignAttributes) { - if (foreignAttributes != null && !foreignAttributes.isEmpty()) { - this.resourceInfo = new ResourceInfo(); - QName resourceNameKey = new QName(AFPElementMapping.NAMESPACE, RESOURCE_NAME); - String resourceName = (String)foreignAttributes.get(resourceNameKey); - if (resourceName != null) { - resourceInfo.setName(resourceName); - } - QName resourceLevelKey = new QName(AFPElementMapping.NAMESPACE, RESOURCE_LEVEL); - if (foreignAttributes.containsKey(resourceLevelKey)) { - String level = (String)foreignAttributes.get(resourceLevelKey); - ResourceLevel resourceLevel = null; - try { - resourceLevel = ResourceLevel.valueOf(level); - resourceInfo.setLevel(resourceLevel); - if (resourceLevel.isExternal()) { - QName resourceGroupFileKey = new QName(AFPElementMapping.NAMESPACE, - RESOURCE_GROUP_FILE); - String resourceExternalDest - = (String)foreignAttributes.get(resourceGroupFileKey); - if (resourceExternalDest == null) { - String msg = RESOURCE_GROUP_FILE + " not specified"; - log.error(msg); - throw new UnsupportedOperationException(msg); - } - File resourceExternalGroupFile = new File(resourceExternalDest); - SecurityManager security = System.getSecurityManager(); - try { - if (security != null) { - security.checkWrite(resourceExternalGroupFile.getPath()); - } - } catch (SecurityException ex) { - log.error("unable to gain write access to external resource file: " - + resourceExternalDest); - } - - try { - boolean exists = resourceExternalGroupFile.exists(); - if (exists) { - log.warn("overwritting external resource file: " - + resourceExternalDest); - } - resourceLevel.setExternalFilePath(resourceExternalDest); - } catch (SecurityException ex) { - log.error("unable to gain read access to external resource file: " - + resourceExternalDest); - } - } - } catch (IllegalArgumentException e) { - // default to print-file resource level if invalid resource level provided - resourceLevel = new ResourceLevel(ResourceLevel.PRINT_FILE); - log.error(e.getMessage() + ", defaulting to '" + resourceLevel + "' level"); - } - } - } - } - - /** {@inheritDoc} */ - public String toString() { - return "mimeType=" + getMimeType() - + (objectAreaInfo != null ? ", objectAreaInfo=" + objectAreaInfo : "") - + (objectType != null ? ", objectType=" + objectType : "") - + (resourceInfo != null ? ", resourceInfo=" + resourceInfo : ""); - } - - /** - * Returns the uri of this data object - * - * @return the uri of this data object - */ - public String getUri() { - return getResourceInfo().getUri(); - } - - /** - * Sets the data object uri - * - * @param uri the data object uri - */ - public void setUri(String uri) { - getResourceInfo().setUri(uri); - } - - /** - * Returns the mime type of this data object - * - * @return the mime type of this data object - */ - public abstract String getMimeType(); - -} diff --git a/src/java/org/apache/fop/render/afp/LineDataInfo.java b/src/java/org/apache/fop/render/afp/LineDataInfo.java index 1fd7f5626..4926f79e6 100644 --- a/src/java/org/apache/fop/render/afp/LineDataInfo.java +++ b/src/java/org/apache/fop/render/afp/LineDataInfo.java @@ -5,9 +5,9 @@ * 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. @@ -23,164 +23,163 @@ import java.awt.Color; /** Line data information */ public class LineDataInfo { - + /** the x1 coordinate */ int x1; - + /** the y1 coordinate */ int y1; - + /** the x2 coordinate */ int x2; - + /** the y2 coordinate */ int y2; - + /** the thickness */ int thickness; - + /** the painting color */ Color color; - + /** the orientation */ int orientation; - + /** * Default constructor */ public LineDataInfo() { } - + /** * Returns the X1 coordinate - * + * * @return the X1 coordinate */ public int getX1() { return x1; } - + /** * Sets the X1 coordinate - * + * * @param x1 the X1 coordinate */ public void setX1(int x1) { this.x1 = x1; } - + /** * Returns the Y1 coordinate - * + * * @return the Y1 coordinate */ public int getY1() { return y1; } - + /** * Sets the Y1 coordinate - * + * * @param y1 the Y1 coordinate */ public void setY1(int y1) { this.y1 = y1; } - + /** * Returns the X2 coordinate - * + * * @return the X2 coordinate */ public int getX2() { return x2; } - + /** * Sets the X2 coordinate - * + * * @param x2 the X2 coordinate */ public void setX2(int x2) { this.x2 = x2; } - + /** * Returns the Y2 coordinate - * + * * @return the Y2 coordinate */ public int getY2() { return y2; } - + /** * Sets the Y2 coordinate - * + * * @param y2 the Y2 coordinate */ public void setY2(int y2) { this.y2 = y2; } - + /** * Returns the line thickness - * + * * @return the line thickness */ public int getThickness() { return thickness; } - + /** * Sets the line thickness - * + * * @param thickness the line thickness */ public void setThickness(int thickness) { this.thickness = thickness; } - + /** * Returns line color - * + * * @return the line color */ public Color getColor() { return color; } - + /** * Sets the line color - * + * * @param color the line color */ public void setColor(Color color) { this.color = color; } - + /** * Returns line orientation - * + * * @return the line orientation */ public int getOrientation() { return orientation; } - + /** * Sets the orientation - * + * * @param orientation the orientation */ public void setOrientation(int orientation) { this.orientation = orientation; } - + /** {@inheritDoc} */ public String toString() { - return "LineDataInfo{" - + ", x1=" + x1 + return "LineDataInfo{x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 + ", y2=" + y2 diff --git a/src/java/org/apache/fop/render/afp/goca/AbstractGraphicsCoord.java b/src/java/org/apache/fop/render/afp/goca/AbstractGraphicsCoord.java index 12d6e13a7..dbb7469fe 100644 --- a/src/java/org/apache/fop/render/afp/goca/AbstractGraphicsCoord.java +++ b/src/java/org/apache/fop/render/afp/goca/AbstractGraphicsCoord.java @@ -31,14 +31,18 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { protected int[] coords = null; /** + * Constructor + * * @param coords the x/y coordinates for this object */ public AbstractGraphicsCoord(int[] coords) { this.coords = coords; prepareData(); } - + /** + * Constructor + * * @param x the x coordinate for this object * @param y the y coordinate for this object */ @@ -47,6 +51,8 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { } /** + * Constructor + * * @param x1 the x1 coordinate for this object * @param y1 the y1 coordinate for this object * @param x2 the x2 coordinate for this object @@ -57,13 +63,17 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { } /** + * Returns the order code to use + * * @return the order code to use */ protected abstract byte getOrderCode(); /** + * Returns the length of this order code (typically this is the same as the coordinate length) + * * @return the length of this order code - * (typically this is the same as the coordinate length) + * */ protected int getLength() { return this.coords.length * 2; @@ -71,6 +81,7 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { /** * Creates a newly created and initialized byte data + * * @return a newly created and initialized byte data */ protected byte[] createData() { @@ -81,9 +92,7 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { return data; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = createData(); int fromIndex = data.length - getLength(); @@ -92,6 +101,7 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { /** * Adds the coordinates to the structured field data + * * @param data the structured field data * @param fromIndex the start index */ @@ -100,11 +110,13 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { for (int i = 0; i < coords.length; i++, fromIndex += 2) { byte[] coord = BinaryUtils.convert(coords[i], 2); data[fromIndex] = coord[0]; - data[fromIndex + 1] = coord[1]; + data[fromIndex + 1] = coord[1]; } } - + /** + * Returns the short name of this GOCA object + * * @return the short name of this GOCA object */ public String getName() { @@ -112,16 +124,14 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject { return className.substring(className.lastIndexOf(".") + 1); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String toString() { String coordsStr = ""; for (int i = 0; i < coords.length; i++) { coordsStr += (i % 2 == 0) ? "x" : "y"; - coordsStr += (i / 2) + "=" + coords[i] + ","; + coordsStr += (i / 2) + "=" + coords[i] + ","; } coordsStr = coordsStr.substring(0, coordsStr.length() - 1); - return getName() + "(" + coordsStr + ")"; - } + return getName() + "{" + coordsStr + "}"; + } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsArea.java b/src/java/org/apache/fop/render/afp/goca/GraphicsArea.java index 46b343eb1..06cc8451f 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsArea.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsArea.java @@ -29,44 +29,39 @@ import org.apache.fop.render.afp.modca.AbstractPreparedObjectContainer; */ public final class GraphicsArea extends AbstractPreparedObjectContainer { + private static final int RES1 = 1; + private static final int BOUNDARY = 2; + private static final int NO_BOUNDARY = 0; + /** draw boundary lines around this area */ private boolean drawBoundary = false; - + /** * Sets whether boundary lines are drawn + * * @param drawBoundaryLines whether boundary lines are drawn */ public void setDrawBoundaryLines(boolean drawBoundaryLines) { this.drawBoundary = drawBoundaryLines; } - - private static final int RES1 = 1; - private static final int BOUNDARY = 2; - private static final int NO_BOUNDARY = 0; - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public int getDataLength() { // start len + end len + data len return 4 + super.getDataLength(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { super.writeStart(os); byte[] data = new byte[] { (byte)0x68, // GBAR order code - (byte)(RES1 + (drawBoundary ? BOUNDARY : NO_BOUNDARY)) + (byte)(RES1 + (drawBoundary ? BOUNDARY : NO_BOUNDARY)) }; os.write(data); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void writeEnd(OutputStream os) throws IOException { byte[] endData = new byte[] { (byte)0x60, // GEAR order code @@ -75,10 +70,8 @@ public final class GraphicsArea extends AbstractPreparedObjectContainer { os.write(endData); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String toString() { - return "GraphicsArea"; + return "GraphicsArea{drawBoundary=" + drawBoundary + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsBox.java b/src/java/org/apache/fop/render/afp/goca/GraphicsBox.java index 8f1bc2378..3daa437f2 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsBox.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsBox.java @@ -25,42 +25,37 @@ package org.apache.fop.render.afp.goca; public final class GraphicsBox extends AbstractGraphicsCoord { /** + * Constructor + * * @param coords the x/y coordinates for this object */ public GraphicsBox(int[] coords) { super(coords); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { return (byte)0xC0; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ protected int getLength() { return 10; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = createData(); final int fromIndex = 4; addCoords(data, fromIndex); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte[] createData() { byte[] data = super.createData(); data[2] = (byte)0x20; // CONTROL draw control flags data[3] = 0x00; // reserved return data; } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsChainedSegment.java b/src/java/org/apache/fop/render/afp/goca/GraphicsChainedSegment.java index 9be20c4cb..89803507c 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsChainedSegment.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsChainedSegment.java @@ -45,7 +45,7 @@ public final class GraphicsChainedSegment extends AbstractPreparedObjectContaine /** * Main constructor - * + * * @param name * the name of this graphics segment */ @@ -55,7 +55,7 @@ public final class GraphicsChainedSegment extends AbstractPreparedObjectContaine /** * Constructor - * + * * @param name * the name of this graphics segment * @param previous @@ -80,21 +80,23 @@ public final class GraphicsChainedSegment extends AbstractPreparedObjectContaine return dataLen; } - /** {@inheritDoc} */ - protected int getNameLength() { - return 4; - } - private static final byte APPEND_NEW_SEGMENT = 0; // private static final byte PROLOG = 4; // private static final byte APPEND_TO_EXISING = 48; + private static final int NAME_LENGTH = 4; + + /** {@inheritDoc} */ + protected int getNameLength() { + return NAME_LENGTH; + } + /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { super.writeStart(os); int len = super.getDataLength(); byte[] segLen = BinaryUtils.convert(len, 2); - + byte[] nameBytes = getNameBytes(); byte[] data = new byte[] { 0x70, // BEGIN_SEGMENT @@ -115,7 +117,7 @@ public final class GraphicsChainedSegment extends AbstractPreparedObjectContaine // P/S NAME (predecessor name) if (previous != null) { nameBytes = previous.getNameBytes(); - System.arraycopy(nameBytes, 0, data, 10, 4); + System.arraycopy(nameBytes, 0, data, 10, NAME_LENGTH); } os.write(data); } @@ -126,7 +128,7 @@ public final class GraphicsChainedSegment extends AbstractPreparedObjectContaine if (previous == null) { GraphicsChainedSegment current = this.next; while (current != null) { - current.write(os); + current.writeToStream(os); current = current.next; } } diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsData.java b/src/java/org/apache/fop/render/afp/goca/GraphicsData.java index d2626ccaf..ad346dfb7 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsData.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsData.java @@ -30,28 +30,20 @@ import org.apache.fop.render.afp.tools.StringUtils; /** * A GOCA graphics data */ -public final class GraphicsData extends AbstractPreparedObjectContainer { - - /** - * The maximum graphics data length - */ +public final class GraphicsData extends AbstractPreparedObjectContainer { + + /** The maximum graphics data length */ public static final int MAX_DATA_LEN = 32767; - /** - * The graphics segment - */ + /** The graphics segment */ private GraphicsChainedSegment currentSegment = null; - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public int getDataLength() { return 8 + super.getDataLength(); } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { super.writeStart(os); int l = getDataLength(); @@ -76,7 +68,7 @@ public final class GraphicsData extends AbstractPreparedObjectContainer { public void beginArea() { getSegment().beginArea(); } - + /** * Ends a graphics area (end of fill) */ @@ -86,16 +78,18 @@ public final class GraphicsData extends AbstractPreparedObjectContainer { /** * Returns a new segment name + * * @return a new segment name */ private String createSegmentName() { return StringUtils.lpad(String.valueOf( (super.objects != null ? super.objects.size() : 0) + 1), - '0', 4); + '0', 4); } - + /** * Returns the current graphics segment, creating one if one does not exist + * * @return the current graphics chained segment */ private GraphicsChainedSegment getSegment() { @@ -107,24 +101,23 @@ public final class GraphicsData extends AbstractPreparedObjectContainer { /** * Creates a new graphics segment + * * @return a newly created graphics segment */ public GraphicsChainedSegment newSegment() { String name = createSegmentName(); if (currentSegment == null) { - this.currentSegment = new GraphicsChainedSegment(name); + this.currentSegment = new GraphicsChainedSegment(name); } else { - this.currentSegment = new GraphicsChainedSegment(name, currentSegment); + this.currentSegment = new GraphicsChainedSegment(name, currentSegment); } super.addObject(currentSegment); return currentSegment; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public PreparedAFPObject addObject(PreparedAFPObject drawingOrder) { - if (currentSegment == null + if (currentSegment == null || (currentSegment.getDataLength() + drawingOrder.getDataLength()) >= GraphicsChainedSegment.MAX_DATA_LEN) { newSegment(); @@ -132,10 +125,8 @@ public final class GraphicsData extends AbstractPreparedObjectContainer { currentSegment.addObject(drawingOrder); return drawingOrder; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { return "GraphicsData"; } diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsFillet.java b/src/java/org/apache/fop/render/afp/goca/GraphicsFillet.java index 122dcd04e..cc1cedf2a 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsFillet.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsFillet.java @@ -5,9 +5,9 @@ * 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. @@ -24,18 +24,19 @@ package org.apache.fop.render.afp.goca; * straight lines drawn from the given position or current position */ public final class GraphicsFillet extends AbstractGraphicsCoord { - + /** + * Constructor + * * @param coords the x/y coordinates for this object */ public GraphicsFillet(int[] coords) { super(coords); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { return (byte)0xC5; } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsFullArc.java b/src/java/org/apache/fop/render/afp/goca/GraphicsFullArc.java index 92ce66d88..41347280e 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsFullArc.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsFullArc.java @@ -5,9 +5,9 @@ * 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. @@ -26,12 +26,14 @@ import org.apache.fop.render.afp.tools.BinaryUtils; */ public class GraphicsFullArc extends AbstractGraphicsCoord { /** the integer portion of the multiplier */ - private int mh; - + private final int mh; + /** the fractional portion of the multiplier */ - private int mhr; - + private final int mhr; + /** + * Constructor + * * @param x the x coordinate of the center of the circle/ellipse * @param y the y coordinate of the center of the circle/ellipse * @param mh the integer portion of the multiplier @@ -44,38 +46,33 @@ public class GraphicsFullArc extends AbstractGraphicsCoord { // integer portion of multiplier data[data.length - 2] = BinaryUtils.convert(mh, 1)[0]; // fractional portion of multiplier - data[data.length - 1] = BinaryUtils.convert(mhr, 1)[0]; + data[data.length - 1] = BinaryUtils.convert(mhr, 1)[0]; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { return (byte)0xC7; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected int getLength() { return super.getLength() + 2; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = super.createData(); final int fromIndex = 2; super.addCoords(data, fromIndex); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String toString() { - return super.getName() - + "(centerx=" + coords[0] + ",centery=" + coords[1] - + ",mh=" + mh + ",mhr=" + mhr + ")"; + return "GraphicsFullArc{" + + ", centerx=" + coords[0] + + ", centery=" + coords[1] + + ", mh=" + mh + + ", mhr=" + mhr + + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsImageBegin.java b/src/java/org/apache/fop/render/afp/goca/GraphicsImage.java index b55a5139d..ed8c1b386 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsImageBegin.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsImage.java @@ -19,48 +19,56 @@ package org.apache.fop.render.afp.goca; -import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractStructuredAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** - * A GOCA graphics begin image object + * A GOCA Image */ -public final class GraphicsImageBegin extends AbstractPreparedAFPObject { +public class GraphicsImage extends AbstractStructuredAFPObject { + /** x coordinate */ - private int x; + private final int x; /** y coordinate */ - private int y; + private final int y; /** width */ - private int width; + private final int width; /** height */ - private int height; + private final int height; + + /** image data */ + private final byte[] imageData; /** + * Main constructor + * * @param x the x coordinate of the image * @param y the y coordinate of the image * @param width the image width * @param height the image height + * @param imageData the image data */ - public GraphicsImageBegin(int x, int y, int width, int height) { + public GraphicsImage(int x, int y, int width, int height, byte[] imageData) { this.x = x; this.y = y; this.width = width; this.height = height; - prepareData(); + this.imageData = imageData; } - /** - * {@inheritDoc} - */ - protected void prepareData() { + /** {@inheritDoc} */ + protected void writeStart(OutputStream os) throws IOException { byte[] xcoord = BinaryUtils.convert(x, 2); byte[] ycoord = BinaryUtils.convert(y, 2); byte[] w = BinaryUtils.convert(width, 2); byte[] h = BinaryUtils.convert(height, 2); - super.data = new byte[] { + byte[] data = new byte[] { (byte) 0xD1, // GBIMG order code (byte) 0x0A, // LENGTH xcoord[0], @@ -74,13 +82,36 @@ public final class GraphicsImageBegin extends AbstractPreparedAFPObject { h[0], // HEIGHT h[1] // }; + os.write(data); } - - /** - * {@inheritDoc} - */ + + /** the maximum image data length */ + public static final short MAX_DATA_LEN = 255; + + /** {@inheritDoc} */ + protected void writeContent(OutputStream os) throws IOException { + byte[] dataHeader = new byte[] { + (byte) 0x92 // GIMD + }; + final int lengthOffset = 1; + writeChunksToStream(imageData, dataHeader, lengthOffset, MAX_DATA_LEN, os); + } + + /** {@inheritDoc} */ + protected void writeEnd(OutputStream os) throws IOException { + byte[] data = new byte[] { + (byte) 0x93, // GEIMG order code + 0x00 // LENGTH + }; + os.write(data); + } + + /** {@inheritDoc} */ public String toString() { - return "GraphicsImageBegin(x=" + x + ",y=" + y - + ",width=" + width + ",height=" + height + ")"; + return "GraphicsImage{x=" + x + + ", y=" + y + + ", width=" + width + + ", height=" + height + + "}"; } -}
\ No newline at end of file +} diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsImageData.java b/src/java/org/apache/fop/render/afp/goca/GraphicsImageData.java deleted file mode 100644 index 1fc7e2332..000000000 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsImageData.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.goca; - -import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject; -import org.apache.fop.render.afp.tools.BinaryUtils; - -/** - * A GOCA graphics image data - */ -public final class GraphicsImageData extends AbstractPreparedAFPObject { - - /** the maximum image data length */ - public static final short MAX_DATA_LEN = 255; - - /** - * Main constructor - * - * @param imageData the image data - * @param startIndex the start index to read the image data from - */ - public GraphicsImageData(byte[] imageData, int startIndex) { - int dataLen = MAX_DATA_LEN; - if (startIndex + MAX_DATA_LEN >= imageData.length) { - dataLen = imageData.length - startIndex - 1; - } - - byte[] data = new byte[dataLen + 2]; - data[0] = (byte) 0x92; // GIMD - data[1] = BinaryUtils.convert(dataLen, 1)[0]; // LENGTH - System.arraycopy(imageData, startIndex, data, 2, dataLen); - - super.setData(data); - } - - /** - * {@inheritDoc} - */ - public String toString() { - return "GraphicsImageData(" - + (data != null ? "" + (data.length - 2) : "null") - + ")"; - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsLine.java b/src/java/org/apache/fop/render/afp/goca/GraphicsLine.java index 306acb448..f09d24d98 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsLine.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsLine.java @@ -27,16 +27,17 @@ package org.apache.fop.render.afp.goca; public class GraphicsLine extends AbstractGraphicsCoord { /** + * Constructor + * * @param coords the x/y coordinates for this object */ public GraphicsLine(int[] coords) { super(coords); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { - return (byte)0xC1; + return (byte)0xC1; } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetArcParameters.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetArcParameters.java index ce9bd1665..26735ed30 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetArcParameters.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetArcParameters.java @@ -25,6 +25,8 @@ package org.apache.fop.render.afp.goca; public class GraphicsSetArcParameters extends AbstractGraphicsCoord { /** + * Constructor + * * @param xmaj x coordinate of the major axis point * @param ymin y coordinate of the minor axis point * @param xmin x coordinate of the minor axis point @@ -34,20 +36,16 @@ public class GraphicsSetArcParameters extends AbstractGraphicsCoord { super(xmaj, ymin, xmin, ymaj); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { return 0x22; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { - return getName() + "(xmaj=" + coords[0] + return getName() + "{xmaj=" + coords[0] + ",ymin=" + coords[1] + ",xmin=" + coords[2] - + ",ymaj=" + coords[3] + ")"; + + ",ymaj=" + coords[3] + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetCharacterSet.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetCharacterSet.java index 2671908c9..f3d8b186b 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetCharacterSet.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetCharacterSet.java @@ -23,11 +23,12 @@ import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** - * Sets the current character set (font) to be used for following graphics strings + * Sets the current character set (font) to be used for following graphics strings */ public class GraphicsSetCharacterSet extends AbstractPreparedAFPObject { + /** font character set reference */ - private int fontReference; + private final int fontReference; /** * @param fontReference character set font reference @@ -37,9 +38,7 @@ public class GraphicsSetCharacterSet extends AbstractPreparedAFPObject { prepareData(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = new byte[] { 0x38, // GSCS order code @@ -47,9 +46,7 @@ public class GraphicsSetCharacterSet extends AbstractPreparedAFPObject { }; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String toString() { return "GraphicsSetCharacterSet(" + fontReference + ")"; } diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetCurrentPosition.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetCurrentPosition.java index 866c37b38..7b68d0f17 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetCurrentPosition.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetCurrentPosition.java @@ -26,15 +26,15 @@ package org.apache.fop.render.afp.goca; public class GraphicsSetCurrentPosition extends AbstractGraphicsCoord { /** + * Constructor + * * @param coords the x/y coordinates for this object */ public GraphicsSetCurrentPosition(int[] coords) { super(coords); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected byte getOrderCode() { return (byte)0x21; } diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineType.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineType.java index 998304d84..febf2dfb2 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineType.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineType.java @@ -5,9 +5,9 @@ * 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. @@ -25,64 +25,62 @@ import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject; * Sets the value of the current line type attribute when stroking GOCA shapes (structured fields) */ public class GraphicsSetLineType extends AbstractPreparedAFPObject { + /** the default line type */ - public static final byte DEFAULT = 0x00; // normally SOLID + public static final byte DEFAULT = 0x00; // normally SOLID /** the default line type */ - public static final byte DOTTED = 0x01; + public static final byte DOTTED = 0x01; /** short dashed line type */ - public static final byte SHORT_DASHED = 0x02; + public static final byte SHORT_DASHED = 0x02; /** dashed dotted line type */ - public static final byte DASH_DOT = 0x03; + public static final byte DASH_DOT = 0x03; /** double dotted line type */ - public static final byte DOUBLE_DOTTED = 0x04; + public static final byte DOUBLE_DOTTED = 0x04; /** long dashed line type */ - public static final byte LONG_DASHED = 0x05; + public static final byte LONG_DASHED = 0x05; /** dash double dotted line type */ - public static final byte DASH_DOUBLE_DOTTED = 0x06; + public static final byte DASH_DOUBLE_DOTTED = 0x06; /** solid line type */ - public static final byte SOLID = 0x07; + public static final byte SOLID = 0x07; /** invisible line type */ public static final byte INVISIBLE = 0x08; - + /** line type */ private byte type = DEFAULT; - + /** * Main constructor + * * @param type line type */ public GraphicsSetLineType(byte type) { this.type = type; prepareData(); } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ protected void prepareData() { super.data = new byte[] { 0x18, // GSLW order code type // line type }; } - + private static final String[] TYPES = { - "DEFAULT", "DOTTED", "SHORT_DASHED", "DASH_DOT", "DOUBLE_DOTTED", - "LONG_DASHED", "DASH_DOUBLE_DOTTED", "SOLID", "INVISIBLE" + "default (solid)", "dotted", "short dashed", "dash dotted", "double dotted", + "long dashed", "dash double dotted", "solid", "invisible" }; - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ public String toString() { - return "GraphicsSetLineType(type=" + TYPES[type] + ")"; + return "GraphicsSetLineType{type=" + TYPES[type] + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineWidth.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineWidth.java index b526f4385..82163d29e 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineWidth.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetLineWidth.java @@ -30,6 +30,7 @@ public class GraphicsSetLineWidth extends AbstractPreparedAFPObject { /** * Main constructor + * * @param multiplier the line width multiplier */ public GraphicsSetLineWidth(int multiplier) { @@ -37,20 +38,16 @@ public class GraphicsSetLineWidth extends AbstractPreparedAFPObject { prepareData(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = new byte[] { 0x19, // GSLW order code (byte)multiplier // MH (line-width) }; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { - return "GraphicsSetLineWidth(multiplier=" + multiplier + ")"; + return "GraphicsSetLineWidth{multiplier=" + multiplier + "}"; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetPatternSymbol.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetPatternSymbol.java index eddb531ed..bdc7b1233 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetPatternSymbol.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetPatternSymbol.java @@ -66,7 +66,7 @@ public class GraphicsSetPatternSymbol extends AbstractPreparedAFPObject { /** diagonal lines, top left to bottom right 2 */ public static final byte DIAGONAL_LINES_TLBR_2 = 0x0E; - + /** no fill */ public static final byte NO_FILL = 0x0F; @@ -75,12 +75,13 @@ public class GraphicsSetPatternSymbol extends AbstractPreparedAFPObject { /** blank (same as no fill) */ public static final byte BLANK = 0x40; // processed same as NO_FILL - + /** the graphics pattern symbol to use */ - private byte symbol; + private final byte symbol; /** * Main constructor + * * @param symb the pattern symbol to use */ public GraphicsSetPatternSymbol(byte symb) { @@ -88,19 +89,15 @@ public class GraphicsSetPatternSymbol extends AbstractPreparedAFPObject { prepareData(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { super.data = new byte[] { 0x28, // GSPT order code symbol }; } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { return "GraphicsSetPatternSymbol(fill=" + (symbol == SOLID_FILL ? true : false) + ")"; diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetProcessColor.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetProcessColor.java index e0dc9ed13..eb8869931 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsSetProcessColor.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetProcessColor.java @@ -30,10 +30,11 @@ import org.apache.fop.render.afp.modca.GraphicsObject; */ public class GraphicsSetProcessColor extends AbstractPreparedAFPObject { /** the color to set */ - private Color col; + private final Color col; /** * Main constructor + * * @param col the color to set */ public GraphicsSetProcessColor(Color col) { @@ -41,9 +42,7 @@ public class GraphicsSetProcessColor extends AbstractPreparedAFPObject { prepareData(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected void prepareData() { // COLSPCE byte colspace; @@ -56,7 +55,7 @@ public class GraphicsSetProcessColor extends AbstractPreparedAFPObject { GraphicsObject.log.error("unsupported colorspace " + colSpaceType); colspace = 0x01; } - + // COLSIZE(S) float[] colcomp = col.getColorComponents(null); byte[] colsizes = new byte[] {0x00, 0x00, 0x00, 0x00}; @@ -66,7 +65,7 @@ public class GraphicsSetProcessColor extends AbstractPreparedAFPObject { int len = 10 + colcomp.length; super.data = new byte[len + 2]; - data[0] = (byte)0xB2; // GSPCOL order code + data[0] = (byte)0xB2; // GSPCOL order code data[1] = (byte)len; // LEN data[2] = 0x00; // reserved; must be zero data[3] = colspace; // COLSPCE @@ -83,10 +82,8 @@ public class GraphicsSetProcessColor extends AbstractPreparedAFPObject { data[i + 12] = (byte)(colcomp[i] * 255); } } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { return "GraphicsSetProcessColor(col=" + col + ")"; } diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsString.java b/src/java/org/apache/fop/render/afp/goca/GraphicsString.java index 1fb842ae4..c5233fb53 100644 --- a/src/java/org/apache/fop/render/afp/goca/GraphicsString.java +++ b/src/java/org/apache/fop/render/afp/goca/GraphicsString.java @@ -35,17 +35,19 @@ public class GraphicsString extends AbstractPreparedAFPObject { /** drawn from the current position */ private boolean fromCurrentPosition = false; - + /** the string to draw */ private String str = null; - + /** x coordinate */ private int x; - + /** y coordinate */ private int y; /** + * Constructor + * * @param str the character string */ public GraphicsString(String str) { @@ -55,6 +57,8 @@ public class GraphicsString extends AbstractPreparedAFPObject { } /** + * Constructor + * * @param str the character string * @param x the x coordinate * @param y the y coordinate @@ -65,10 +69,8 @@ public class GraphicsString extends AbstractPreparedAFPObject { this.y = y; prepareData(); } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ protected void prepareData() { int maxStrLen = MAX_STR_LEN - (fromCurrentPosition ? 0 : 4); if (str.length() > maxStrLen) { @@ -89,7 +91,7 @@ public class GraphicsString extends AbstractPreparedAFPObject { System.arraycopy(strData, 0, data, 2, strData.length); } else { len += 4; // x/y coordinates - byte[] osx = BinaryUtils.convert(x, 2); + byte[] osx = BinaryUtils.convert(x, 2); byte[] osy = BinaryUtils.convert(y, 2); data = new byte[len + 2]; data[0] = (byte)0xC3; @@ -101,16 +103,14 @@ public class GraphicsString extends AbstractPreparedAFPObject { System.arraycopy(strData, 0, data, 6, strData.length); } } - - /** - * {@inheritDoc} - */ + + /** {@inheritDoc} */ public String toString() { - String string = "GraphicsString(str='" + str + "'"; + String string = "GraphicsString{str='" + str + "'"; if (!fromCurrentPosition) { string += ",x=" + x + ",y=" + y; } - string += ")"; + string += "}"; return string; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java b/src/java/org/apache/fop/render/afp/ioca/ImageCellPosition.java index 5f1f95932..4faac0c6e 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageCellPosition.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageCellPosition.java @@ -17,10 +17,12 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -42,22 +44,22 @@ public class ImageCellPosition extends AbstractAFPObject { /** * Size of image cell in X direction */ - private byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF}; + private final byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF}; /** * Size of image cell in Y direction */ - private byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF}; + private final byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF}; /** * Size of fill rectangle in X direction */ - private byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; + private final byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; /** * Size of fill rectangle in Y direction */ - private byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; + private final byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF}; /** * Constructor for the ImageCellPosition @@ -70,10 +72,10 @@ public class ImageCellPosition extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[21]; copySF(data, Type.POSITION, Category.IM_IMAGE); - + data[1] = 0x00; // length data[2] = 0x14; @@ -113,6 +115,7 @@ public class ImageCellPosition extends AbstractAFPObject { * 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) { @@ -129,6 +132,7 @@ public class ImageCellPosition extends AbstractAFPObject { * 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) { @@ -142,6 +146,7 @@ public class ImageCellPosition extends AbstractAFPObject { * 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) { @@ -158,6 +163,7 @@ public class ImageCellPosition extends AbstractAFPObject { * 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) { diff --git a/src/java/org/apache/fop/render/afp/modca/ImageContent.java b/src/java/org/apache/fop/render/afp/ioca/ImageContent.java index b63da87d9..a0e14e12e 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageContent.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageContent.java @@ -17,11 +17,12 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.tools.BinaryUtils; + +import org.apache.fop.render.afp.modca.AbstractStructuredAFPObject; /** */ @@ -34,7 +35,7 @@ public class ImageContent extends AbstractStructuredAFPObject { * one-dimensional compression. */ public static final byte COMPID_G3_MH = (byte)0x80; - + /** * The CCITT T.4 Group 3 Coding Option (G3 MR-Modified READ) is a * compression method standardized by the International Telegraph and @@ -47,7 +48,7 @@ public class ImageContent extends AbstractStructuredAFPObject { * The CCITT T.6 Group 4 Coding Standard (G4 MMR-Modified Modified READ) is a * compression method standardized by the International Telegraph and * Telephone Consultative Committee (CCITT) for facsimile. It enables - * two-dimensional compression. + * two-dimensional compression. */ public static final byte COMPID_G3_MMR = (byte)0x82; @@ -79,7 +80,7 @@ public class ImageContent extends AbstractStructuredAFPObject { /** * The image data */ - private byte[] imageData = null; + private byte[] data; /** * Constructor for the image content @@ -90,142 +91,133 @@ public class ImageContent extends AbstractStructuredAFPObject { /** * 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. + * @param hresol The horizontal resolution of the image. + * @param vresol The vertical resolution of the image. */ - public void setImageSize(int hresol, int vresol, int hsize, int vsize) { - imageSizeParameter = new ImageSizeParameter(hresol, vresol, hsize, vsize); + public void setImageSize(int hsize, int vsize, int hresol, int vresol) { + imageSizeParameter = new ImageSizeParameter(hsize, vsize, hresol, vresol); } /** * Sets the image encoding. - * - * @param encoding The image encoding. + * + * @param enc The image encoding. */ - public void setImageEncoding(byte encoding) { - this.encoding = encoding; + public void setImageEncoding(byte enc) { + this.encoding = enc; } /** * Sets the image compression. - * - * @param compression The image compression. + * + * @param comp The image compression. */ - public void setImageCompression(byte compression) { - this.compression = compression; + public void setImageCompression(byte comp) { + this.compression = comp; } /** * Sets the image IDE size. - * - * @param size The IDE size. + * + * @param s The IDE size. */ - public void setImageIDESize(byte size) { - this.size = size; + public void setImageIDESize(byte s) { + this.size = s; } /** * Sets the image IDE color model. - * - * @param colorModel the IDE color model. + * + * @param color the IDE color model. */ - public void setImageIDEColorModel(byte colorModel) { - this.colorModel = colorModel; + public void setImageIDEColorModel(byte color) { + this.colorModel = color; } /** - * Set the data of the image. - * - * @param data the image data + * Set the data image store information. + * + * @param imageData the image data */ - public void setImageData(byte[] data) { - this.imageData = data; + public void setImageData(byte[] imageData) { + this.data = imageData; } + private static final int MAX_DATA_LEN = 65535; + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { if (imageSizeParameter != null) { - imageSizeParameter.write(os); + imageSizeParameter.writeToStream(os); } + + // TODO convert to triplet/parameter class os.write(getImageEncodingParameter()); + os.write(getImageIDESizeParameter()); + os.write(getIDEStructureParameter()); + os.write(getExternalAlgorithmParameter()); - if (imageData != null) { - int off = 0; - while (off < imageData.length) { - int len = Math.min(30000, imageData.length - off); - os.write(getImageDataStart(len)); - os.write(imageData, off, len); - off += len; - } + + // Image Data + if (data != null) { + final byte[] dataHeader = new byte[] { + (byte)0xFE, // ID + (byte)0x92, // ID + 0x00, // length + 0x00 // length + }; + final int lengthOffset = 2; + writeChunksToStream(this.data, dataHeader, lengthOffset, MAX_DATA_LEN, os); } } /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { - byte[] data = new byte[] { + final byte[] startData = new byte[] { (byte)0x91, // ID 0x01, // Length (byte)0xff, // Object Type = IOCA Image Object }; - os.write(data); + os.write(startData); } /** {@inheritDoc} */ protected void writeEnd(OutputStream os) throws IOException { - byte[] data = new byte[] { + final byte[] endData = 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; + os.write(endData); } /** * Helper method to return the image encoding parameter. - * + * * @return byte[] The data stream. */ private byte[] getImageEncodingParameter() { - byte[] data = new byte[] { + final byte[] encodingData = new byte[] { (byte)0x95, // ID 0x02, // Length encoding, 0x01, // RECID }; - return data; + return encodingData; } /** * 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[] { + final byte[] extAlgData = new byte[] { (byte)0x95, // ID 0x00, // Length 0x10, // ALGTYPE = Compression Algorithm @@ -239,35 +231,35 @@ public class ImageContent extends AbstractStructuredAFPObject { 0x00, // Reserved 0x00, // Reserved }; - data[1] = (byte)(data.length - 2); - return data; + extAlgData[1] = (byte)(extAlgData.length - 2); + return extAlgData; } return new byte[0]; } /** * Helper method to return the image encoding parameter. - * + * * @return byte[] The data stream. */ private byte[] getImageIDESizeParameter() { - byte[] data = new byte[] { + final byte[] ideSizeData = new byte[] { (byte)0x96, // ID 0x01, // Length size, }; - return data; + return ideSizeData; } /** * 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[] { + final byte bits = (byte)(size / 3); + final byte[] ideStructData = new byte[] { (byte)0x9B, // ID 0x00, // Length 0x00, // FLAGS @@ -280,8 +272,8 @@ public class ImageContent extends AbstractStructuredAFPObject { bits, bits, }; - data[1] = (byte)(data.length - 2); - return data; + ideStructData[1] = (byte)(ideStructData.length - 2); + return ideStructData; } return new byte[0]; } diff --git a/src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java b/src/java/org/apache/fop/render/afp/ioca/ImageInputDescriptor.java index 0ae81996b..cb6595eaf 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageInputDescriptor.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageInputDescriptor.java @@ -17,10 +17,12 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -37,11 +39,11 @@ public class ImageInputDescriptor extends AbstractAFPObject { /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[45]; copySF(data, Type.DESCRIPTOR, Category.IM_IMAGE); - + data[1] = 0x00; // length data[2] = 0x2C; @@ -126,7 +128,7 @@ public class ImageInputDescriptor extends AbstractAFPObject { /** * 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) { diff --git a/src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java b/src/java/org/apache/fop/render/afp/ioca/ImageOutputControl.java index 4ba78f161..1758f4a16 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageOutputControl.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageOutputControl.java @@ -17,10 +17,12 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -72,7 +74,7 @@ public class ImageOutputControl extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[33]; diff --git a/src/java/org/apache/fop/render/afp/modca/ImageRasterData.java b/src/java/org/apache/fop/render/afp/ioca/ImageRasterData.java index f015c6955..0c863e1e7 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageRasterData.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageRasterData.java @@ -17,10 +17,14 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractAFPObject; +import org.apache.fop.render.afp.modca.AbstractAFPObject.Category; +import org.apache.fop.render.afp.modca.AbstractAFPObject.Type; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -48,7 +52,7 @@ public class ImageRasterData extends AbstractAFPObject { /** * The image raster data */ - private byte[] rasterData; + private final byte[] rasterData; /** * Constructor for the image raster data object @@ -59,16 +63,15 @@ public class ImageRasterData extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[9]; copySF(data, Type.DATA, Category.IM_IMAGE); - // The size of the structured field byte[] len = BinaryUtils.convert(rasterData.length + 8, 2); data[1] = len[0]; data[2] = len[1]; - 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/ioca/ImageRasterPattern.java index 373e50631..9619c40ff 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageRasterPattern.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageRasterPattern.java @@ -17,7 +17,7 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; /** * Raster data is a grid of cells covering an area of interest. diff --git a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java b/src/java/org/apache/fop/render/afp/ioca/ImageSegment.java index 5dda07557..e5e1bbd23 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageSegment.java @@ -17,11 +17,14 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; +import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; +import org.apache.fop.render.afp.modca.Factory; + /** * 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 @@ -35,119 +38,102 @@ import java.io.OutputStream; public class ImageSegment extends AbstractNamedAFPObject { /** - * Default name for the object environment group - */ - private static final String DEFAULT_NAME = "IS000001"; - - /** * The ImageContent for the image segment */ private ImageContent imageContent = null; - /** - * Default constructor for the ImageSegment. - */ - public ImageSegment() { - this(DEFAULT_NAME); - } + private final Factory factory; /** * 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. + * @param factory the object factory + * + * @param name the name of the image. */ - public ImageSegment(String name) { + public ImageSegment(Factory factory, String name) { super(name); + this.factory = factory; } - /** {@inheritDoc} */ - protected int getNameLength() { - return 4; + private ImageContent getImageContent() { + if (imageContent == null) { + this.imageContent = factory.createImageContent(); + } + return 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. + * @param hresol The horizontal resolution of the image. + * @param vresol The vertical resolution 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); + public void setImageSize(int hsize, int vsize, int hresol, int vresol) { + getImageContent().setImageSize(hsize, vsize, hresol, vresol); } /** * Sets the image encoding. - * + * * @param encoding The image encoding. */ - public void setImageEncoding(byte encoding) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageEncoding(encoding); + public void setEncoding(byte encoding) { + getImageContent().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); + public void setCompression(byte compression) { + getImageContent().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); + public void setIDESize(byte size) { + getImageContent().setImageIDESize(size); } /** * Sets the image IDE color model. - * - * @param colorModel the IDE color model. + * + * @param colorModel the IDE color model. */ - public void setImageIDEColorModel(byte colorModel) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageIDEColorModel(colorModel); + public void setIDEColorModel(byte colorModel) { + getImageContent().setImageIDEColorModel(colorModel); } /** - * Set the data of the image. - * + * Set the data image data. + * * @param data the image data */ - public void setImageData(byte[] data) { - if (imageContent == null) { - imageContent = new ImageContent(); - } - imageContent.setImageData(data); + public void setData(byte[] data) { + getImageContent().setImageData(data); } /** {@inheritDoc} */ public void writeContent(OutputStream os) throws IOException { if (imageContent != null) { - imageContent.write(os); + imageContent.writeToStream(os); } } + private static final int NAME_LENGTH = 4; + + /** {@inheritDoc} */ + protected int getNameLength() { + return NAME_LENGTH; + } + /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] nameBytes = getNameBytes(); diff --git a/src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java b/src/java/org/apache/fop/render/afp/ioca/ImageSizeParameter.java index 0506b7bdc..e2c408200 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageSizeParameter.java +++ b/src/java/org/apache/fop/render/afp/ioca/ImageSizeParameter.java @@ -17,10 +17,12 @@ /* $Id$ */ -package org.apache.fop.render.afp.modca; +package org.apache.fop.render.afp.ioca; import java.io.IOException; import java.io.OutputStream; + +import org.apache.fop.render.afp.modca.AbstractAFPObject; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -28,28 +30,29 @@ import org.apache.fop.render.afp.tools.BinaryUtils; */ public class ImageSizeParameter extends AbstractAFPObject { - private int hRes = 0; - private int vRes = 0; private int hSize = 0; private int vSize = 0; + private int hRes = 0; + private int vRes = 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. + * @param hresol The horizontal resolution of the image. + * @param vresol The vertical resolution of the image. */ - public ImageSizeParameter(int hresol, int vresol, int hsize, int vsize) { - this.hRes = hresol; - this.vRes = vresol; + public ImageSizeParameter(int hsize, int vsize, int hresol, int vresol) { this.hSize = hsize; this.vSize = vsize; + this.hRes = hresol; + this.vRes = vresol; } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[] { (byte)0x94, // ID = Image Size Parameter 0x09, // Length diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java index 7a530456f..45e6c68e4 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java @@ -26,61 +26,62 @@ import java.util.Iterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.util.store.Streamable; /** * 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 implements Writable { +public abstract class AbstractAFPObject implements Streamable { /** Static logging instance */ protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca"); + /** the structured field class id */ protected static final byte SF_CLASS = (byte)0xD3; - - private static final byte[] SF = new byte[] { + + private static final byte[] SF_HEADER = new byte[] { 0x5A, // Structured field identifier 0x00, // Length byte 1 0x10, // Length byte 2 - (byte) SF_CLASS, // Structured field id byte 1 + SF_CLASS, // Structured field id byte 1 (byte) 0x00, // Structured field id byte 2 (byte) 0x00, // Structured field id byte 3 0x00, // Flags 0x00, // Reserved - 0x00, // Reserved - }; + 0x00, // Reserved + }; /** * Copies the template structured field data array to the given byte array - * + * * @param data the structured field data byte array * @param type the type code * @param category the category code */ protected void copySF(byte[] data, byte type, byte category) { copySF(data, SF_CLASS, type, category); - } + } /** * Copies the template structured field data array to the given byte array - * + * * @param data the structured field data byte array * @param clazz the class code * @param type the type code * @param category the category code */ - protected void copySF(byte[] data, byte clazz, byte type, byte category) { - System.arraycopy(SF, 0, data, 0, SF.length); + protected static void copySF(byte[] data, byte clazz, byte type, byte category) { + System.arraycopy(SF_HEADER, 0, data, 0, SF_HEADER.length); data[3] = clazz; data[4] = type; data[5] = category; - } + } /** * Help method to write a set of AFPObjects to the AFP datastream. - * + * * @param objects a list of AFPObjects * @param os The stream to write to * @throws java.io.IOException an I/O exception of some sort has occurred. @@ -89,151 +90,153 @@ public abstract class AbstractAFPObject implements Writable { throws IOException { if (objects != null) { for (Iterator it = objects.iterator(); it.hasNext();) { - AbstractAFPObject obj = (AbstractAFPObject)it.next(); - obj.write(os); + Object object = it.next(); + if (object instanceof Streamable) { + ((Streamable)object).writeToStream(os); + } } } } - + /** structured field type codes */ - interface Type { - - // Attribute + public interface Type { + + /** Attribute */ byte ATTRIBUTE = (byte)0x0A; - - // Copy Count + + /** Copy Count */ byte COPY_COUNT = (byte)0xA2; - - // Descriptor + + /** Descriptor */ byte DESCRIPTOR = (byte)0xA6; - - // Control + + /** Control */ byte CONTROL = (byte)0xA7; - - // Begin + + /** Begin */ byte BEGIN = (byte)0xA8; - - // End + + /** End */ byte END = (byte)0xA9; - - // Map + + /** Map */ byte MAP = (byte)0xAB; - - // Position + + /** Position */ byte POSITION = (byte)0xAC; - - // Process + + /** Process */ byte PROCESS = (byte)0xAD; - - // Include + + /** Include */ byte INCLUDE = (byte)0xAF; - - // Table + + /** Table */ byte TABLE = (byte)0xB0; - - // Migration + + /** Migration */ byte MIGRATION = (byte)0xB1; - - // Variable + + /** Variable */ byte VARIABLE = (byte)0xB2; - - // Link + + /** Link */ byte LINK = (byte)0xB4; - - // Data + + /** Data */ byte DATA = (byte)0xEE; } - + /** structured field category codes */ - interface Category { - - // Page Segment + public interface Category { + + /** Page Segment */ byte PAGE_SEGMENT = (byte)0x5F; - // Object Area + /** Object Area */ byte OBJECT_AREA = (byte)0x6B; - - // Color Attribute Table + + /** Color Attribute Table */ byte COLOR_ATTRIBUTE_TABLE = (byte)0x77; - // IM Image + /** IM Image */ byte IM_IMAGE = (byte)0x7B; - - // Medium + + /** Medium */ byte MEDIUM = (byte)0x88; - - // Coded Font + + /** Coded Font */ byte CODED_FONT = (byte)0x8A; - - // Process Element + + /** Process Element */ byte PROCESS_ELEMENT = (byte)0x90; - // Object Container + /** Object Container */ byte OBJECT_CONTAINER = (byte)0x92; - // Presentation Text + /** Presentation Text */ byte PRESENTATION_TEXT = (byte)0x9B; - // Index + /** Index */ byte INDEX = (byte)0xA7; - - // Document + + /** Document */ byte DOCUMENT = (byte)0xA8; - - // Page Group + + /** Page Group */ byte PAGE_GROUP = (byte)0xAD; - - // Page + + /** Page */ byte PAGE = (byte)0xAF; - - // Graphics + + /** Graphics */ byte GRAPHICS = (byte)0xBB; - - // Data Resource + + /** Data Resource */ byte DATA_RESOURCE = (byte)0xC3; - - // Document Environment Group (DEG) + + /** Document Environment Group (DEG) */ byte DOCUMENT_ENVIRONMENT_GROUP = (byte)0xC4; - - // Resource Group + + /** Resource Group */ byte RESOURCE_GROUP = (byte)0xC6; - // Object Environment Group (OEG) + /** Object Environment Group (OEG) */ byte OBJECT_ENVIRONMENT_GROUP = (byte)0xC7; - - // Active Environment Group (AEG) + + /** Active Environment Group (AEG) */ byte ACTIVE_ENVIRONMENT_GROUP = (byte)0xC9; - - // Medium Map + + /** Medium Map */ byte MEDIUM_MAP = (byte)0xCC; - - // Form Map + + /** Form Map */ byte FORM_MAP = (byte)0xCD; - - // Name Resource + + /** Name Resource */ byte NAME_RESOURCE = (byte)0xCE; - - // Page Overlay + + /** Page Overlay */ byte PAGE_OVERLAY = (byte)0xD8; - - // Resource Environment Group (REG) + + /** Resource Environment Group (REG) */ byte RESOURCE_ENVIROMENT_GROUP = (byte)0xD9; - - // Overlay + + /** Overlay */ byte OVERLAY = (byte)0xDF; - - // Data Suppression + + /** Data Suppression */ byte DATA_SUPRESSION = (byte)0xEA; - - // Bar Code + + /** Bar Code */ byte BARCODE = (byte)0xEB; - - // No Operation + + /** No Operation */ byte NO_OPERATION = (byte)0xEE; - - // Image + + /** Image */ byte IMAGE = (byte)0xFB; } - + } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java index f666de38b..8eccbcc2e 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java @@ -5,9 +5,9 @@ * 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. @@ -22,62 +22,60 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.ObjectAreaInfo; +import org.apache.fop.render.afp.AFPDataObjectInfo; +import org.apache.fop.render.afp.AFPObjectAreaInfo; /** * Abstract base class used by the ImageObject and GraphicsObject which both * have define an ObjectEnvironmentGroup */ -public abstract class AbstractDataObject extends AbstractPreparedObjectContainer { +public abstract class AbstractDataObject extends AbstractNamedAFPObject { - /** The object environment group */ + /** the object environment group */ protected ObjectEnvironmentGroup objectEnvironmentGroup = null; + /** the object factory */ + protected final Factory factory; + /** * Named constructor - * + * + * @param factory the object factory * @param name data object name */ - public AbstractDataObject(String name) { + public AbstractDataObject(Factory factory, String name) { super(name); + this.factory = factory; } - + /** - * Sets the object display area position and size. + * Sets the object view port (area position and size). * - * @param objectAreaInfo + * @param dataObjectInfo * the object area info */ - public void setViewport(ObjectAreaInfo objectAreaInfo) { + public void setViewport(AFPDataObjectInfo dataObjectInfo) { + AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); getObjectEnvironmentGroup().setObjectArea(objectAreaInfo); } - + /** * Gets the ObjectEnvironmentGroup - * + * * @return the object environment group */ protected ObjectEnvironmentGroup getObjectEnvironmentGroup() { if (objectEnvironmentGroup == null) { - objectEnvironmentGroup = new ObjectEnvironmentGroup(); + this.objectEnvironmentGroup = factory.createObjectEnvironmentGroup(); } return objectEnvironmentGroup; } - - /** - * Sets the ObjectEnvironmentGroup. - * - * @param objectEnvironmentGroup The objectEnvironmentGroup to set - */ - public void setObjectEnvironmentGroup(ObjectEnvironmentGroup objectEnvironmentGroup) { - this.objectEnvironmentGroup = objectEnvironmentGroup; - } /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { + super.writeContent(os); if (objectEnvironmentGroup != null) { - objectEnvironmentGroup.write(os); + objectEnvironmentGroup.writeToStream(os); } - super.writeContent(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 index 728008e96..2ec5feac2 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractDescriptor.java @@ -33,9 +33,15 @@ public abstract class AbstractDescriptor extends AbstractStructuredAFPObject { protected int heightRes = 0; /** + * Default constructor + */ + public 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 widthRes The width resolution of the page. @@ -47,4 +53,12 @@ public abstract class AbstractDescriptor extends AbstractStructuredAFPObject { this.widthRes = widthRes; this.heightRes = heightRes; } + + /** {@inheritDoc} */ + public String toString() { + return "width=" + width + + ", height=" + height + + ", widthRes=" + widthRes + + ", heightRes=" + heightRes; + } } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java index 463058791..558ad61ba 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java @@ -45,24 +45,34 @@ public abstract class AbstractNamedAFPObject extends AbstractStructuredAFPObject /** * Constructor for the ActiveEnvironmentGroup, this takes a * name parameter which should be 8 characters long. - * + * * @param name the object name */ protected AbstractNamedAFPObject(String name) { this.name = name; } - + + /** + * Returns the name length + * + * @return the name length + */ + protected int getNameLength() { + return DEFAULT_NAME_LENGTH; + } + /** * Returns the name as a byte array in EBCIDIC encoding - * + * * @return the name as a byte array in EBCIDIC encoding */ protected byte[] getNameBytes() { - if (name.length() < DEFAULT_NAME_LENGTH) { - name = (name + " ").substring(0, DEFAULT_NAME_LENGTH); - } else if (name.length() > DEFAULT_NAME_LENGTH) { - log.warn("Constructor:: name truncated to " + DEFAULT_NAME_LENGTH + " chars" + name); - name = name.substring(0, DEFAULT_NAME_LENGTH); + int nameLen = getNameLength(); + if (name.length() < nameLen) { + name = (name + " ").substring(0, nameLen); + } else if (name.length() > nameLen) { + log.warn("Constructor:: name truncated to " + nameLen + " chars" + name); + name = name.substring(0, nameLen); } byte[] nameBytes = null; try { @@ -85,7 +95,7 @@ public abstract class AbstractNamedAFPObject extends AbstractStructuredAFPObject /** * Returns the name of this object - * + * * @return the name of this object */ public String getName() { diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java index 8f4742950..c986e7eca 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java @@ -21,15 +21,11 @@ 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.fop.render.afp.LineDataInfo; import org.apache.fop.render.afp.TextDataInfo; import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.modca.resource.ResourceManager; -import org.apache.fop.render.afp.modca.resource.ResourceStore; -import org.apache.fop.render.afp.modca.resource.StoreInfo; /** * Pages contain the data objects that comprise a presentation document. Each @@ -53,9 +49,6 @@ import org.apache.fop.render.afp.modca.resource.StoreInfo; */ public abstract class AbstractPageObject extends AbstractNamedAFPObject { - /** The resource manager */ - protected ResourceManager resourceManager; - /** The active environment group for the page */ protected ActiveEnvironmentGroup activeEnvironmentGroup = null; @@ -66,10 +59,11 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { protected List/*<TagLogicalElement>*/ tagLogicalElements = null; /** The list of the include page segments */ - protected List/*<IncludePageSegment>*/ includePageSegments = null; + protected List/*<IncludePageSegment>*/ includePageSegments + = new java.util.ArrayList/*<IncludePageSegment>*/(); /** The list of objects within this resource container */ - protected List/*<AbstractStructuredAFPObject>*/ objects = null; + protected List/*<AbstractStructuredAFPObject>*/ objects = new java.util.ArrayList(); /** The page width */ private int width; @@ -81,7 +75,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { protected int rotation = 0; /** The page state */ - private boolean complete = false; + protected boolean complete = false; /** The width resolution */ private int widthRes; @@ -89,27 +83,35 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** The height resolution */ private int heightRes; - /** Default constructor */ - public AbstractPageObject() { + /** the object factory */ + protected final Factory factory; + + /** + * Default constructor + * + * @param factory the object factory + */ + public AbstractPageObject(Factory factory) { + this.factory = factory; } /** * Main constructor - * - * @param resourceManager the resource manager + * + * @param factory the object factory * @param name the name of this page object */ - public AbstractPageObject(ResourceManager resourceManager, String name) { + public AbstractPageObject(Factory factory, String name) { super(name); - this.resourceManager = resourceManager; + this.factory = factory; } /** * Construct a new page object for the specified name argument, the page * name should be an 8 character identifier. - * - * @param resourceManager the resource manager * + * @param factory + * the object factory. * @param name * the name of the page. * @param width @@ -123,10 +125,11 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { * @param heightRes * the height resolution of the page. */ - public AbstractPageObject(ResourceManager resourceManager, + public AbstractPageObject(Factory factory, String name, int width, int height, int rotation, int widthRes, int heightRes) { - this(resourceManager, name); + super(name); + this.factory = factory; this.width = width; this.height = height; this.rotation = rotation; @@ -153,7 +156,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * 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 lineDataInfo the line data information. */ public void createLine(LineDataInfo lineDataInfo) { @@ -182,28 +185,32 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { complete = true; } - private void endPresentationObject() { + /** + * Ends the presentation text object + */ + protected void endPresentationObject() { if (currentPresentationTextObject != null) { currentPresentationTextObject.endControlSequence(); currentPresentationTextObject = null; } } - + /** * Helper method to create a presentation text object * on the current page and to return the object. - * + * * @return the presentation text object */ private PresentationTextObject getPresentationTextObject() { if (currentPresentationTextObject == null) { - PresentationTextObject presentationTextObject = new PresentationTextObject(); + PresentationTextObject presentationTextObject + = factory.createPresentationTextObject(); addObject(presentationTextObject); this.currentPresentationTextObject = presentationTextObject; } return currentPresentationTextObject; } - + /** * Creates a TagLogicalElement on the page. * @@ -234,16 +241,13 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { * * @param name * the name of the page segment - * @param xCoor + * @param x * the x coordinate of the page segment. - * @param yCoor + * @param y * the y coordinate of the page segment. */ - public void createIncludePageSegment(String name, int xCoor, int yCoor) { - IncludePageSegment ips = new IncludePageSegment(name, xCoor, yCoor); - if (includePageSegments == null) { - includePageSegments = new java.util.ArrayList/*<IncludePageSegment>*/(); - } + public void createIncludePageSegment(String name, int x, int y) { + IncludePageSegment ips = factory.createIncludePageSegment(name, x, y); includePageSegments.add(ips); } @@ -257,8 +261,8 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * Every page object must have an ActiveEnvironmentGroup */ - this.activeEnvironmentGroup = new ActiveEnvironmentGroup( - width, height, widthRes, heightRes); + this.activeEnvironmentGroup + = factory.createActiveEnvironmentGroup(width, height, widthRes, heightRes); if (rotation != 0) { switch (rotation) { @@ -280,7 +284,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * Returns an indication if the page is complete - * + * * @return whether this page is complete */ public boolean isComplete() { @@ -289,7 +293,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * Returns the height of the page - * + * * @return the height of the page */ public int getHeight() { @@ -298,7 +302,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * Returns the width of the page - * + * * @return the width of the page */ public int getWidth() { @@ -307,48 +311,30 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject { /** * Returns the rotation of the page - * + * * @return the rotation of the page */ public int getRotation() { return rotation; } - + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); if (this instanceof PageObject || this instanceof Overlay) { - getActiveEnvironmentGroup().write(os); + getActiveEnvironmentGroup().writeToStream(os); } writeObjects(this.includePageSegments, os); writeObjects(this.tagLogicalElements, os); - - // Write objects from cache - Iterator it = objects.iterator(); - if (it.hasNext()) { - ResourceStore store = resourceManager.getStore(); - do { - Object obj = it.next(); - if (obj instanceof Writable) { - Writable writableObject = (Writable)obj; - writableObject.write(os); - } else if (obj instanceof StoreInfo) { - StoreInfo storeInfo = (StoreInfo)obj; - store.writeToStream(storeInfo, os); - } - } while (it.hasNext()); - } + writeObjects(this.objects, os); } - + /** * Adds an AFP object reference to this page - * + * * @param obj an AFP object */ - protected void addObject(Object obj) { - if (objects == null) { - this.objects = new java.util.ArrayList(); - } + public void addObject(Object obj) { objects.add(obj); } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractPreparedObjectContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractPreparedObjectContainer.java index 7fcd0095d..f16d2df81 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractPreparedObjectContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractPreparedObjectContainer.java @@ -5,9 +5,9 @@ * 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. @@ -29,7 +29,7 @@ import java.util.List; */ public abstract class AbstractPreparedObjectContainer extends AbstractNamedAFPObject implements PreparedAFPObject { - + /** list of objects contained within this container */ protected List/*<PreparedAFPObject>*/ objects = null; @@ -41,18 +41,16 @@ implements PreparedAFPObject { /** * Named constructor - * + * * @param name the name of the container */ protected AbstractPreparedObjectContainer(String name) { super(name); } - + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { - if (objects != null) { - super.writeObjects(objects, os); - } + super.writeObjects(objects, os); } private List/*<PreparedAFPObject>*/ getObjects() { @@ -61,10 +59,10 @@ implements PreparedAFPObject { } return this.objects; } - + /** * Adds a given prepared object to this container - * + * * @param preparedObject the prepared object * @return the drawingOrder if it was added, null otherwise */ @@ -72,10 +70,10 @@ implements PreparedAFPObject { getObjects().add(preparedObject); return preparedObject; } - + /** * Returns the current data length - * + * * @return the current data length of this container including * all enclosed objects (and their containers) */ @@ -91,5 +89,5 @@ implements PreparedAFPObject { } } return dataLen; - } + } } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java index 6eb8268e5..cb7d4d387 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java @@ -5,9 +5,9 @@ * 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. @@ -22,11 +22,10 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.modca.resource.ResourceManager; /** - * An abstract class which encapsulates the common features of - * Document and PageGroup resource containers + * An abstract class which encapsulates the common features of + * Document and PageGroup resource containers */ public abstract class AbstractResourceEnvironmentGroupContainer extends AbstractResourceGroupContainer { @@ -38,17 +37,18 @@ public abstract class AbstractResourceEnvironmentGroupContainer /** * Main constructor - * - * @param resourceManager the resource manager + * + * @param factory the object factory * @param name the name of this resource container */ - public AbstractResourceEnvironmentGroupContainer(ResourceManager resourceManager, String name) { - super(resourceManager, name); + public AbstractResourceEnvironmentGroupContainer( + Factory factory, String name) { + super(factory, name); } /** * Adds a page to the resource container. - * + * * @param page - the Page object */ public void addPage(PageObject page) { @@ -57,7 +57,7 @@ public abstract class AbstractResourceEnvironmentGroupContainer /** * Adds a PageGroup to the resource container. - * + * * @param pageGroup the PageGroup object */ public void addPageGroup(PageGroup pageGroup) { @@ -78,13 +78,13 @@ public abstract class AbstractResourceEnvironmentGroupContainer protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); if (resourceEnvironmentGroup != null) { - resourceEnvironmentGroup.write(os); + resourceEnvironmentGroup.writeToStream(os); } } - + /** * Returns the resource environment group - * + * * @return the resource environment group */ protected ResourceEnvironmentGroup getResourceEnvironmentGroup() { @@ -92,5 +92,5 @@ public abstract class AbstractResourceEnvironmentGroupContainer this.resourceEnvironmentGroup = new ResourceEnvironmentGroup(); } return this.resourceEnvironmentGroup; - } + } } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java index b3739c717..066a21b8e 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java @@ -5,9 +5,9 @@ * 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. @@ -22,41 +22,40 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.modca.resource.ResourceManager; /** * An abstract container of resource objects */ public abstract class AbstractResourceGroupContainer extends AbstractPageObject { - /** - * The resource group object - */ + /** the resource group object */ private ResourceGroup resourceGroup = null; /** * Default constructor + * + * @param factory the object factory */ - public AbstractResourceGroupContainer() { - super(); + public AbstractResourceGroupContainer(Factory factory) { + super(factory); } /** * Named constructor - * - * @param resourceManager the resource manager + * + * @param factory the object factory * @param name the name of this resource container */ - public AbstractResourceGroupContainer(ResourceManager resourceManager, String name) { - super(resourceManager, name); + public AbstractResourceGroupContainer(Factory factory, String name) { + super(factory, name); } /** * Construct a new page object for the specified name argument, the page * name should be an 8 character identifier. - * - * @param resourceManager - * the resource manager + * + * @param factory + * the object factory * @param name * the name of the page. * @param width @@ -70,14 +69,14 @@ public abstract class AbstractResourceGroupContainer extends AbstractPageObject * @param heightRes * the height resolution of the page. */ - public AbstractResourceGroupContainer(ResourceManager resourceManager, String name, int width, int height, - int rotation, int widthRes, int heightRes) { - super(resourceManager, name, width, height, rotation, widthRes, heightRes); + public AbstractResourceGroupContainer(Factory factory, + String name, int width, int height, int rotation, int widthRes, int heightRes) { + super(factory, name, width, height, rotation, widthRes, heightRes); } /** * Return the number of resources in this container - * + * * @return the number of resources in this container */ protected int getResourceCount() { @@ -86,30 +85,32 @@ public abstract class AbstractResourceGroupContainer extends AbstractPageObject } return 0; } - + /** * Returns true if this resource group container contains resources - * + * * @return true if this resource group container contains resources */ protected boolean hasResources() { return resourceGroup != null && resourceGroup.getResourceCount() > 0; } - + /** + * Returns the resource group in this resource group container + * * @return the resource group in this resource group container */ protected ResourceGroup getResourceGroup() { if (resourceGroup == null) { - resourceGroup = resourceManager.getFactory().createResourceGroup(); + resourceGroup = factory.createResourceGroup(); } return resourceGroup; } - + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { if (resourceGroup != null) { - resourceGroup.write(os); + resourceGroup.writeToStream(os); } super.writeContent(os); } diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java index b3a3c7afb..070ee1edb 100644 --- a/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java +++ b/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java @@ -5,9 +5,9 @@ * 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. @@ -19,7 +19,6 @@ package org.apache.fop.render.afp.modca; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; @@ -27,6 +26,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet; import org.apache.fop.render.afp.modca.triplets.MappingOptionTriplet; import org.apache.fop.render.afp.modca.triplets.MeasurementUnitsTriplet; @@ -34,16 +34,17 @@ import org.apache.fop.render.afp.modca.triplets.ObjectAreaSizeTriplet; import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet; import org.apache.fop.render.afp.modca.triplets.StrucFlgs; import org.apache.fop.render.afp.modca.triplets.Triplet; +import org.apache.fop.render.afp.tools.BinaryUtils; /** * An abstract class encapsulating an MODCA structured object */ -public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { +public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * list of object triplets */ protected List/*<Triplet>*/ triplets = null; - + /** * triplet data created from triplet list */ @@ -54,10 +55,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { */ protected AbstractStructuredAFPObject() { } - + /** * Returns the triplet data length - * + * * @return the triplet data length */ protected int getTripletDataLength() { @@ -73,10 +74,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { } return 0; } - + /** * Returns the triplet data - * + * * @return the triplet data * @throws IOException throws an I/O exception if one occurred */ @@ -88,10 +89,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { } return this.tripletData; } - + /** * Writes any triplet data - * + * * @param os The stream to write to * @throws IOException The stream to write to */ @@ -100,12 +101,12 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { os.write(tripletData); } else if (triplets != null) { writeObjects(triplets, os); - } + } } /** * Helper method to write the start of the Object. - * + * * @param os The stream to write to * @throws IOException throws an I/O exception if one occurred */ @@ -115,7 +116,7 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Helper method to write the end of the Object. - * + * * @param os The stream to write to * @throws IOException an I/O exception if one occurred */ @@ -124,21 +125,16 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Helper method to write the contents of the Object. - * + * * @param os The stream to write to * @throws IOException throws an I/O exception if one occurred */ protected void writeContent(OutputStream os) throws IOException { writeTriplets(os); } - - /** - * Accessor method to write the AFP datastream for this structure field object - * - * @param os The stream to write to - * @throws IOException in the event that an I/O exception occurred - */ - public void write(OutputStream os) throws IOException { + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { writeStart(os); writeContent(os); writeEnd(os); @@ -146,7 +142,7 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Returns the first matching triplet found in the structured field triplet list - * + * * @param tripletId the triplet identifier */ private Triplet getTriplet(byte tripletId) { @@ -159,20 +155,20 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { } return null; } - + /** * Returns true of this structured field has the given triplet - * + * * @param tripletId the triplet identifier * @return true if the structured field has the given triplet */ - private boolean hasTriplet(byte tripletId) { + public boolean hasTriplet(byte tripletId) { return getTriplet(tripletId) != null; } /** * Adds a triplet to this structured object - * + * * @param triplet the triplet to add */ private void addTriplet(Triplet triplet) { @@ -181,10 +177,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Adds a list of triplets to the triplets contained within this structured field - * + * * @param tripletCollection a collection of triplets */ - private void addTriplets(Collection/*<Triplet>*/ tripletCollection) { + public void addTriplets(Collection/*<Triplet>*/ tripletCollection) { if (tripletCollection != null) { getTriplets().addAll(tripletCollection); } @@ -197,10 +193,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { } return triplets; } - + /** * Sets the fully qualified name of this resource - * + * * @param fqnType the fully qualified name type of this resource * @param fqnFormat the fully qualified name format of this resource * @param fqName the fully qualified name of this resource @@ -219,10 +215,10 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { log.warn(this + " has no fully qualified name"); return null; } - + /** * Sets the objects classification - * + * * @param objectClass the classification of the object * @param objectType the MOD:CA registry object type entry for the given * object/component type of the object @@ -235,18 +231,18 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Sets the objects classification with the default structure flags - * + * * @param objectClass the classification of the object * @param objectType the MOD:CA registry object type entry for the given * object/component type of the object */ public void setObjectClassification(byte objectClass, Registry.ObjectType objectType) { - setObjectClassification(objectClass, objectType, StrucFlgs.getDefault()); + setObjectClassification(objectClass, objectType, StrucFlgs.DEFAULT); } - + /** * Sets the extent of an object area in the X and Y directions - * + * * @param x the x direction extent * @param y the y direction extent */ @@ -256,7 +252,7 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Sets the measurement units used to specify the units of measure - * + * * @param xRes units per base on the x-axis * @param yRes units per base on the y-axis */ @@ -266,16 +262,16 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { /** * Sets the mapping option - * + * * @param optionValue the mapping option value */ public void setMappingOption(byte optionValue) { addTriplet(new MappingOptionTriplet(optionValue)); } - + /** * Sets a comment on this resource - * + * * @param comment a comment string */ public void setComment(String comment) { @@ -285,4 +281,49 @@ public abstract class AbstractStructuredAFPObject extends AbstractAFPObject { log.error(e.getMessage()); } } + + /** + * Writes data chunks to a given outputstream + * + * @param data the data + * @param dataHeader the header data + * @param lengthOffset offset of length field in data chunk + * @param maxChunkLength the maximum chunk length + * @param os the outputstream to write to + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + protected static void writeChunksToStream(byte[] data, byte[] dataHeader, + int lengthOffset, int maxChunkLength, OutputStream os) throws IOException { + int dataLength = data.length; + int numFullChunks = dataLength / maxChunkLength; + int lastChunkLength = dataLength % maxChunkLength; + + int headerLen = dataHeader.length - lengthOffset; + // length field is just before data so do not include in data length + if (headerLen == 2) { + headerLen = 0; + } + + byte[] len; + int off = 0; + if (numFullChunks > 0) { + // write out full data chunks + len = BinaryUtils.convert(headerLen + maxChunkLength, 2); + dataHeader[lengthOffset] = len[0]; // Length byte 1 + dataHeader[lengthOffset + 1] = len[1]; // Length byte 2 + for (int i = 0; i < numFullChunks; i++, off += maxChunkLength) { + os.write(dataHeader); + os.write(data, off, maxChunkLength); + } + } + + if (lastChunkLength > 0) { + // write last data chunk + len = BinaryUtils.convert(headerLen + lastChunkLength, 2); + dataHeader[lengthOffset] = len[0]; // Length byte 1 + dataHeader[lengthOffset + 1] = len[1]; // Length byte 2 + os.write(dataHeader); + os.write(data, off, lastChunkLength); + } + } } diff --git a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java index 916544603..c254ef17b 100644 --- a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java @@ -40,66 +40,44 @@ import org.apache.fop.render.afp.fonts.AFPFont; */ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { - /** - * Default name for the active environment group - */ - private static final String DEFAULT_NAME = "AEG00001"; - - /** - * The collection of MapCodedFont objects - */ - private List mapCodedFonts = null; + /** The collection of MapCodedFont objects */ + private List/*<MapCodedFonts>*/ mapCodedFonts = null; - /** - * The collection of MapDataResource objects - */ - private List mapDataResources = null; + /** the collection of MapDataResource objects */ + private final List mapDataResources = null; - /** - * The Object Area Descriptor for the active environment group - */ + /** the Object Area Descriptor for the active environment group */ private ObjectAreaDescriptor objectAreaDescriptor = null; - /** - * The Object Area Position for the active environment group - */ + /** the Object Area Position for the active environment group */ private ObjectAreaPosition objectAreaPosition = null; - /** - * The PresentationTextDescriptor for the active environment group - */ + /** the PresentationTextDescriptor for the active environment group */ private PresentationTextDescriptor presentationTextDataDescriptor = null; - /** - * The PageDescriptor for the active environment group - */ + /** the PageDescriptor for the active environment group */ private PageDescriptor pageDescriptor = null; - /** - * Default constructor for the ActiveEnvironmentGroup. - * - * @param width the page width - * @param height the page height - * @param widthRes the page width resolution - * @param heightRes the page height resolution - */ - public ActiveEnvironmentGroup(int width, int height, int widthRes, int heightRes) { - this(DEFAULT_NAME, width, height, widthRes, heightRes); - } + /** the resource manager */ + private final Factory factory; /** * Constructor for the ActiveEnvironmentGroup, this takes a * name parameter which must be 8 characters long. - * + * + * @param factory the object factory * @param name the active environment group name * @param width the page width * @param height the page height * @param widthRes the page width resolution * @param heightRes the page height resolution */ - public ActiveEnvironmentGroup(String name, int width, int height, int widthRes, int heightRes) { + public ActiveEnvironmentGroup(Factory factory, + String name, int width, int height, int widthRes, int heightRes) { super(name); + this.factory = factory; + // Create PageDescriptor pageDescriptor = new PageDescriptor(width, height, widthRes, heightRes); @@ -114,7 +92,7 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { /** * Set the position of the object area - * + * * @param x the x offset * @param y the y offset * @param rotation the rotation @@ -127,7 +105,7 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { /** * Accessor method to obtain the PageDescriptor object of the * active environment group. - * + * * @return the page descriptor object */ public PageDescriptor getPageDescriptor() { @@ -137,7 +115,7 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { /** * Accessor method to obtain the PresentationTextDataDescriptor object of * the active environment group. - * + * * @return the presentation text descriptor */ public PresentationTextDescriptor getPresentationTextDataDescriptor() { @@ -147,20 +125,20 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { /** {@inheritDoc} */ public void writeContent(OutputStream os) throws IOException { super.writeTriplets(os); - + writeObjects(mapCodedFonts, os); writeObjects(mapDataResources, os); writeObjects(mapPageOverlays, os); - + if (pageDescriptor != null) { - pageDescriptor.write(os); + pageDescriptor.writeToStream(os); } if (objectAreaDescriptor != null && objectAreaPosition != null) { - objectAreaDescriptor.write(os); - objectAreaPosition.write(os); + objectAreaDescriptor.writeToStream(os); + objectAreaPosition.writeToStream(os); } if (presentationTextDataDescriptor != null) { - presentationTextDataDescriptor.write(os); + presentationTextDataDescriptor.writeToStream(os); } } @@ -185,16 +163,9 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { return mapCodedFonts; } -// private List getMapDataResources() { -// if (mapDataResources == null) { -// mapDataResources = new java.util.ArrayList(); -// } -// return mapDataResources; -// } - /** * Method to create a map coded font object - * + * * @param fontRef the font number used as the resource identifier * @param font the font * @param size the point size of the font @@ -203,14 +174,14 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { public void createFont(int fontRef, AFPFont font, int size, int orientation) { MapCodedFont mcf = getCurrentMapCodedFont(); if (mcf == null) { - mcf = new MapCodedFont(); + mcf = factory.createMapCodedFont(); getMapCodedFonts().add(mcf); } try { mcf.addFont(fontRef, font, size, orientation); } catch (MaximumSizeExceededException msee) { - mcf = new MapCodedFont(); + mcf = factory.createMapCodedFont(); getMapCodedFonts().add(mcf); try { @@ -225,7 +196,7 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { /** * 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() { @@ -236,7 +207,14 @@ public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup { return null; } } - + +// private List getMapDataResources() { +// if (mapDataResources == null) { +// mapDataResources = new java.util.ArrayList(); +// } +// return mapDataResources; +//} + // /** // * Method to create a map data resource object // * @param dataObjectAccessor a data object accessor diff --git a/src/java/org/apache/fop/render/afp/modca/ContainerDataDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ContainerDataDescriptor.java new file mode 100644 index 000000000..41fb67384 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/ContainerDataDescriptor.java @@ -0,0 +1,81 @@ +/* + * 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; + +/** + * Container data descriptor (to maintain compatibility with pre-year 2000 applications) + */ +public class ContainerDataDescriptor extends AbstractDescriptor { + + /** + * Main constructor + * + * @param width the container data width + * @param height the container data height + * @param widthRes the container width resolution + * @param heightRes the container height resolution + */ + public ContainerDataDescriptor(int width, int height, int widthRes, + int heightRes) { + super(width, height, widthRes, heightRes); + } + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + byte[] data = new byte[21]; + copySF(data, Type.DESCRIPTOR, Category.IMAGE); + + // SF length + byte[] len = BinaryUtils.convert(data.length - 1, 2); + data[1] = len[0]; + data[2] = len[1]; + + data[9] = 0x00; // XocBase = 10 inches + data[10] = 0x00; // YocBase = 10 inches + + // XocUnits + byte[] xdpi = BinaryUtils.convert(widthRes * 10, 2); + data[11] = xdpi[0]; + data[12] = xdpi[1]; + + // YocUnits + byte[] ydpi = BinaryUtils.convert(heightRes * 10, 2); + data[13] = ydpi[0]; + data[14] = ydpi[1]; + + // XocSize + byte[] x = BinaryUtils.convert(width, 3); + data[15] = x[0]; + data[16] = x[1]; + data[17] = x[2]; + + // YocSize + byte[] y = BinaryUtils.convert(height, 3); + data[18] = y[0]; + data[19] = y[1]; + data[20] = y[2]; + } + +} diff --git a/src/java/org/apache/fop/render/afp/modca/DataObjectAccessor.java b/src/java/org/apache/fop/render/afp/modca/DataObjectAccessor.java deleted file mode 100644 index b1d8aeb2a..000000000 --- a/src/java/org/apache/fop/render/afp/modca/DataObjectAccessor.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; - -import org.apache.fop.render.afp.DataObjectInfo; - -/** - * A common interface of ResourceObject and ContainerObject - */ -public interface DataObjectAccessor extends Writable { - - /** - * @return the actual data object referenced in this envelope - */ - AbstractNamedAFPObject getDataObject(); - - /** - * @return the data object info relating to the data object - */ - DataObjectInfo getDataObjectInfo(); - - /** - * Sets the data object info - * @param dataObjectInfo the data object info - */ - void setDataObjectInfo(DataObjectInfo dataObjectInfo); - - /** - * @return the data object accessor name - */ - String getName(); -} diff --git a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java b/src/java/org/apache/fop/render/afp/modca/DataStream.java index 041768cd4..0b1c2e052 100644 --- a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java +++ b/src/java/org/apache/fop/render/afp/modca/DataStream.java @@ -27,18 +27,11 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.apache.fop.render.afp.AFPFontAttributes; +import org.apache.fop.render.afp.AFPResourceLevel; import org.apache.fop.render.afp.LineDataInfo; import org.apache.fop.render.afp.TextDataInfo; -import org.apache.fop.render.afp.DataObjectInfo; -import org.apache.fop.render.afp.ObjectAreaInfo; -import org.apache.fop.render.afp.ResourceInfo; -import org.apache.fop.render.afp.ResourceLevel; import org.apache.fop.render.afp.fonts.AFPFont; -import org.apache.fop.render.afp.modca.resource.ResourceFactory; -import org.apache.fop.render.afp.modca.resource.ResourceManager; -import org.apache.fop.render.afp.modca.resource.StoreInfo; import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet; /** @@ -56,7 +49,7 @@ import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet; * is accommodated by including resource objects in the documents that reference * them. */ -public class AFPDataStream extends AbstractResourceGroupContainer { +public class DataStream { /** Static logging instance */ protected static Log log = LogFactory.getLog("org.apache.fop.render.afp.modca"); @@ -67,7 +60,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** The application producing the AFP document */ // not used // private String producer = null; - + /** The AFP document object */ private Document document = null; @@ -92,30 +85,37 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** The rotation */ private int orientation; - /** The outputstream for the data stream */ - private OutputStream outputStream = null; - - /** Maintain a reference count of instream objects for referencing purposes */ - private int instreamObjectCount = 0; - /** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */ private InterchangeSet interchangeSet = InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2); - private ResourceFactory factory; + private final Factory factory; + + private OutputStream outputStream; /** - * Default constructor for the AFPDataStream. + * Default constructor for the AFPDocumentStream. + * + * @param factory the resource factory + * @param outputStream the outputstream to write to */ - public AFPDataStream() { - this.resourceManager = new ResourceManager(); - this.factory = resourceManager.getFactory(); - this.document = factory.createDocument(); + public DataStream(Factory factory, OutputStream outputStream) { + this.factory = factory; + this.outputStream = outputStream; + } + + /** + * Returns the outputstream + * + * @return the outputstream + */ + public OutputStream getOutputStream() { + return this.outputStream; } /** * Returns the document object - * + * * @return the document object */ private Document getDocument() { @@ -124,10 +124,10 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** * Returns the current page - * + * * @return the current page */ - protected AbstractPageObject getCurrentPage() { + public AbstractPageObject getCurrentPage() { return this.currentPage; } @@ -146,18 +146,8 @@ public class AFPDataStream extends AbstractResourceGroupContainer { } } - /** - * Sets the OutputStream - * - * @param outputStream - * the AFP OutputStream - */ - public void setOutputStream(OutputStream outputStream) { - this.outputStream = outputStream; - } - /** {@inheritDoc} */ - public void write() throws IOException { + public void endDocument() throws IOException { if (complete) { String msg = "Invalid state - document already ended."; log.warn("endDocument():: " + msg); @@ -174,20 +164,10 @@ public class AFPDataStream extends AbstractResourceGroupContainer { endPageGroup(); } - if (interchangeSet.supportsLevel2()) { - // Write out any external resource groups - resourceManager.writeExternal(); - - // Write out any print-file level resources - if (hasResources()) { - getResourceGroup().write(this.outputStream); - } - } - // Write out document if (document != null) { document.endDocument(); - document.write(this.outputStream); + document.writeToStream(this.outputStream); } this.outputStream.flush(); @@ -197,10 +177,6 @@ public class AFPDataStream extends AbstractResourceGroupContainer { this.document = null; this.outputStream = null; - - this.resourceManager.clearStore(); - - this.resourceManager = null; } /** @@ -221,7 +197,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer { public void startPage(int pageWidth, int pageHeight, int pageRotation, int pageWidthRes, int pageHeightRes) { currentPageObject = factory.createPage(pageWidth, pageHeight, - pageRotation, pageWidthRes, pageHeightRes); + pageRotation, pageWidthRes, pageHeightRes); currentPage = currentPageObject; currentOverlay = null; } @@ -258,8 +234,10 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** * Helper method to mark the end of the current overlay. + * + * @throws IOException thrown if an I/O exception of some sort has occurred */ - public void endOverlay() { + public void endOverlay() throws IOException { if (currentOverlay != null) { currentOverlay.endPage(); currentOverlay = null; @@ -297,18 +275,22 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** * Helper method to mark the end of the current page. + * + * @throws IOException thrown if an I/O exception of some sort has occurred */ - public void endPage() { + public void endPage() throws IOException { if (currentPageObject != null) { currentPageObject.endPage(); if (currentPageGroup != null) { currentPageGroup.addPage(currentPageObject); + currentPageGroup.writeToStream(this.outputStream); } else { document.addPage(currentPageObject); + document.writeToStream(this.outputStream); } + currentPageObject = null; + currentPage = null; } - currentPageObject = null; - currentPage = null; } /** @@ -328,14 +310,14 @@ public class AFPDataStream extends AbstractResourceGroupContainer { /** * Sets the orientation to be used for element positioning - * + * * @param orientation * the orientation used for element positioning */ public void setOrientation(int orientation) { this.orientation = orientation; } - + /** * Creates the given page fonts in the current page * @@ -365,7 +347,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer { * the point size of the font */ public void createFont(int fontReference, AFPFont font, int size) { - getCurrentPage().createFont(fontReference, font, size); + currentPage.createFont(fontReference, font, size); } /** @@ -377,156 +359,17 @@ public class AFPDataStream extends AbstractResourceGroupContainer { */ public void createText(TextDataInfo textDataInfo) { textDataInfo.setOrientation(orientation); - getCurrentPage().createText(textDataInfo); + currentPage.createText(textDataInfo); } /** - * Creates a data object in the datastream. The data object resides - * according to its type, info and MO:DCA-L (resource) support. - * - * @param dataObjectInfo the data object info - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public void createObject(DataObjectInfo dataObjectInfo) throws IOException { - ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); - String uri = resourceInfo.getUri(); - - if (uri == null) { - uri = "/"; - } - // if this is an instream data object adjust uri to ensure that it is - // unique - if (uri.endsWith("/")) { - uri += "#" + (++instreamObjectCount); - resourceInfo.setUri(uri); - } - - // Update placement with current state - ObjectAreaInfo areaInfo = dataObjectInfo.getObjectAreaInfo(); - areaInfo.setX(areaInfo.getX()); - areaInfo.setY(areaInfo.getY()); - areaInfo.setRotation(this.rotation); - - // Do we have a recognised/registered object type? - Registry registry = Registry.getInstance(); - Registry.ObjectType objectType = registry.getObjectType(dataObjectInfo); - if (objectType != null) { - dataObjectInfo.setObjectType(objectType); - } else { - log.info("Unknown object type for '" + dataObjectInfo + "'"); - } - - StoreInfo storeInfo = resourceManager.create(dataObjectInfo); - - if (objectType != null) { - - ResourceLevel resourceLevel = resourceInfo.getLevel(); - - // is MO:DCA-L available? - if (interchangeSet.supportsLevel2()) { - - // Can this data object use the include object (IOB) referencing - // mechanism? - if (objectType.isIncludable()) { - - // Create and return include - String objectName = storeInfo.getObjectName(); - IncludeObject includeObj = factory.createInclude(objectName, dataObjectInfo); - getCurrentPage().addObject(includeObj); - - // Record the resource cache key (uri) in the ResourceGroup - ResourceGroup resourceGroup = getResourceGroup(resourceLevel); - resourceGroup.addObject(storeInfo); - return; - } else { - log.warn("Data object located at '" + uri + "'" - + " of type '" + objectType.getMimeType() + "'" - + " cannot be referenced with an include" - + " so it will be embedded directly in the page"); - } - } else { - if (resourceLevel.isExternal()) { - log.warn(interchangeSet - + ": not available, object " + getName() + " will reside inline"); - } - } - } - // Unrecognised/unsupported object type so add object reference directly in current page - currentPageObject.addObject(storeInfo); - } - -// /** -// * Sets the object view port taking into account rotation. -// * -// * @param x -// * the x position of the object -// * @param y -// * the y position of the object -// * @param w -// * the width of the object -// * @param h -// * the height of the object -// * @param wr -// * the resolution width of the object -// * @param hr -// * the resolution height of the object -// * @return a new graphics object -// */ -// private void setObjectViewPort(AbstractDataObject dataObj, int x, int y, -// int w, int h, int wr, int hr) { -// int xOrigin; -// int yOrigin; -// int width; -// int height; -// int widthRes; -// int heightRes; -// switch (this.rotation) { -// case 90: -// xOrigin = getCurrentPage().getWidth() - y - yOffset; -// yOrigin = x + xOffset; -// width = h; -// height = w; -// widthRes = hr; -// heightRes = wr; -// break; -// case 180: -// xOrigin = getCurrentPage().getWidth() - x - xOffset; -// yOrigin = getCurrentPage().getHeight() - y - yOffset; -// width = w; -// height = h; -// widthRes = wr; -// heightRes = hr; -// break; -// case 270: -// xOrigin = y + yOffset; -// yOrigin = getCurrentPage().getHeight() - x - xOffset; -// width = h; -// height = w; -// widthRes = hr; -// heightRes = wr; -// break; -// default: -// xOrigin = x + xOffset; -// yOrigin = y + yOffset; -// width = w; -// height = h; -// widthRes = wr; -// heightRes = hr; -// break; -// } -// dataObj.setViewport(xOrigin, yOrigin, width, height, widthRes, -// heightRes, rotation); -// } - - /** * Method to create a line on the current page. * * @param lineDataInfo the line data information. */ public void createLine(LineDataInfo lineDataInfo) { lineDataInfo.setOrientation(orientation); - getCurrentPage().createLine(lineDataInfo); + currentPage.createLine(lineDataInfo); } /** @@ -568,7 +411,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer { * the name of the medium map */ public void createInvokeMediumMap(String name) { - getCurrentPageGroup().createInvokeMediumMap(name); + currentPageGroup.createInvokeMediumMap(name); } /** @@ -586,23 +429,23 @@ public class AFPDataStream extends AbstractResourceGroupContainer { int yOrigin; switch (orientation) { case 90: - xOrigin = getCurrentPage().getWidth() - y; + xOrigin = currentPage.getWidth() - y; yOrigin = x; break; case 180: - xOrigin = getCurrentPage().getWidth() - x; - yOrigin = getCurrentPage().getHeight() - y; + xOrigin = currentPage.getWidth() - x; + yOrigin = currentPage.getHeight() - y; break; case 270: xOrigin = y; - yOrigin = getCurrentPage().getHeight() - x; + yOrigin = currentPage.getHeight() - x; break; default: xOrigin = x; yOrigin = y; break; } - getCurrentPage().createIncludePageSegment(name, xOrigin, yOrigin); + currentPage.createIncludePageSegment(name, xOrigin, yOrigin); } /** @@ -613,9 +456,9 @@ public class AFPDataStream extends AbstractResourceGroupContainer { */ 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(); - getCurrentPage().createTagLogicalElement(name, value); + String name = attributes[i].getKey(); + String value = attributes[i].getValue(); + currentPage.createTagLogicalElement(name, value); } } @@ -627,9 +470,9 @@ public class AFPDataStream extends AbstractResourceGroupContainer { */ 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(); - getCurrentPageGroup().createTagLogicalElement(name, value); + String name = attributes[i].getKey(); + String value = attributes[i].getValue(); + currentPageGroup.createTagLogicalElement(name, value); } } @@ -645,7 +488,7 @@ public class AFPDataStream extends AbstractResourceGroupContainer { if (currentPageGroup != null) { currentPageGroup.createTagLogicalElement(name, value); } else { - getCurrentPage().createTagLogicalElement(name, value); + currentPage.createTagLogicalElement(name, value); } } @@ -656,37 +499,50 @@ public class AFPDataStream extends AbstractResourceGroupContainer { * byte data */ public void createNoOperation(String content) { - getCurrentPage().createNoOperation(content); + currentPage.createNoOperation(content); } /** * Returns the current page group - * + * * @return the current page group */ - private PageGroup getCurrentPageGroup() { - if (currentPageGroup == null) { - this.currentPageGroup = factory.createPageGroup(); - } - return currentPageGroup; + public PageGroup getCurrentPageGroup() { + return this.currentPageGroup; + } + + /** + * Start a new document. + * + * @throws IOException thrown if an I/O exception of some sort has occurred + */ + public void startDocument() throws IOException { + this.document = factory.createDocument(); + document.writeToStream(this.outputStream); } /** * 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. + * + * @throws IOException thrown if an I/O exception of some sort has occurred */ - public void startPageGroup() { - getCurrentPageGroup(); + public void startPageGroup() throws IOException { + endPageGroup(); + this.currentPageGroup = factory.createPageGroup(); } /** * 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() { + public void endPageGroup() throws IOException { if (currentPageGroup != null) { currentPageGroup.endPageGroup(); - getDocument().addPageGroup(currentPageGroup); + document.addPageGroup(currentPageGroup); + document.writeToStream(outputStream); currentPageGroup = null; } } @@ -724,25 +580,22 @@ public class AFPDataStream extends AbstractResourceGroupContainer { } /** - * Sets the default resource group file + * Sets the MO:DCA interchange set to use * - * @param filePath the default resource group file path + * @param interchangeSet the MO:DCA interchange set */ - public void setDefaultResourceGroupFilePath(String filePath) { - resourceManager.getExternalManager().setDefaultFilePath(filePath); + public void setInterchangeSet(InterchangeSet interchangeSet) { + this.interchangeSet = interchangeSet; } -// /** -// * Returns the external resource group manager -// * -// * @return the resource group manager -// */ -// protected ExternalResourceGroupManager getExternalResourceGroupManager() { -// if (externalResourceGroupManager == null) { -// this.externalResourceGroupManager = new ExternalResourceGroupManager(); -// } -// return this.externalResourceGroupManager; -// } + /** + * Returns the MO:DCA interchange set in use + * + * @return the MO:DCA interchange set in use + */ + public InterchangeSet getInterchangeSet() { + return this.interchangeSet; + } /** * Returns the resource group for a given resource info @@ -750,43 +603,16 @@ public class AFPDataStream extends AbstractResourceGroupContainer { * @param level a resource level * @return a resource group for the given resource info */ - private ResourceGroup getResourceGroup(ResourceLevel level) { + public ResourceGroup getResourceGroup(AFPResourceLevel level) { ResourceGroup resourceGroup = null; - if (level.isExternal()) { - resourceGroup = resourceManager.getExternalManager().getResourceGroup(level); - // use print-file level resource group in the absence - // of an external resource group file definition - if (resourceGroup == null) { - level.setLevel(ResourceLevel.PRINT_FILE); - } - } - if (level.isPrintFile()) { - resourceGroup = getResourceGroup(); - } else if (level.isDocument()) { - resourceGroup = getDocument().getResourceGroup(); + if (level.isDocument()) { + resourceGroup = document.getResourceGroup(); } else if (level.isPageGroup()) { - resourceGroup = getCurrentPageGroup().getResourceGroup(); + resourceGroup = currentPageGroup.getResourceGroup(); } else if (level.isPage()) { resourceGroup = currentPageObject.getResourceGroup(); - } + } return resourceGroup; } - /** - * Sets the MO:DCA interchange set to use - * - * @param interchangeSet the MO:DCA interchange set - */ - public void setInterchangeSet(InterchangeSet interchangeSet) { - this.interchangeSet = interchangeSet; - } - - /** - * Returns the MO:DCA interchange set in use - * - * @return the MO:DCA interchange set in use - */ - public InterchangeSet getInterchangeSet() { - return this.interchangeSet; - } } diff --git a/src/java/org/apache/fop/render/afp/modca/Document.java b/src/java/org/apache/fop/render/afp/modca/Document.java index 469f3fc1e..04fb6c8c8 100644 --- a/src/java/org/apache/fop/render/afp/modca/Document.java +++ b/src/java/org/apache/fop/render/afp/modca/Document.java @@ -21,19 +21,19 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; +import java.util.Iterator; -import org.apache.fop.render.afp.modca.resource.ResourceManager; +import org.apache.fop.util.store.Streamable; /** * 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. + * 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. + * 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 @@ -41,42 +41,32 @@ import org.apache.fop.render.afp.modca.resource.ResourceManager; * 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. + * 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 AbstractResourceEnvironmentGroupContainer { +public final class Document extends AbstractResourceEnvironmentGroupContainer implements Streamable { - /** - * Static default generated name reference - */ - private static final String DEFAULT_NAME = "DOC00001"; - - /** - * The document completion state - */ - private boolean complete = false; + /** The document started state */ + private boolean started = false; - /** - * Default constructor for the document object. - * @param resourceManager the resource manager - */ - public Document(ResourceManager resourceManager) { - this(resourceManager, DEFAULT_NAME); - } + /** The document completion state */ + private boolean complete = false; /** * Constructor for the document object. - * - * @param resourceManager the resource manager - * @param name the name of the document + * + * @param factory + * the object factory + * @param name + * the name of the document */ - public Document(ResourceManager resourceManager, String name) { - super(resourceManager, name); + public Document(Factory factory, String name) { + super(factory, name); } /** @@ -88,25 +78,13 @@ public final class Document extends AbstractResourceEnvironmentGroupContainer { /** * 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 write(OutputStream os) throws IOException { - if (isComplete()) { - super.write(os); - } - } - /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; @@ -120,9 +98,33 @@ public final class Document extends AbstractResourceEnvironmentGroupContainer { copySF(data, Type.END, Category.DOCUMENT); os.write(data); } - + /** {@inheritDoc} */ public String toString() { return this.name; } + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + if (!started) { + writeStart(os); + started = true; + } + + Iterator it = objects.iterator(); + while (it.hasNext()) { + AbstractAFPObject ao = (AbstractAFPObject)it.next(); + if (ao instanceof PageGroup && ((PageGroup)ao).isComplete() + || ao instanceof PageObject && ((PageObject)ao).isComplete()) { + ao.writeToStream(os); + it.remove(); + } else { + break; + } + } + + if (complete) { + writeEnd(os); + } + } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/Factory.java b/src/java/org/apache/fop/render/afp/modca/Factory.java new file mode 100644 index 000000000..5879cb081 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/Factory.java @@ -0,0 +1,522 @@ +/* + * 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.OutputStream; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.afp.goca.GraphicsData; +import org.apache.fop.render.afp.ioca.ImageContent; +import org.apache.fop.render.afp.ioca.ImageRasterData; +import org.apache.fop.render.afp.ioca.ImageSegment; +import org.apache.fop.render.afp.tools.StringUtils; + +/** + * Creator of MO:DCA data objects (mostly) + */ +public class Factory { + + /** Static logging instance */ + private static final Log log = LogFactory.getLog(Factory.class); + + private static final String OBJECT_ENVIRONMENT_GROUP_NAME_PREFIX = "OEG"; + + private static final String ACTIVE_ENVIRONMENT_GROUP_NAME_PREFIX = "AEG"; + + private static final String IMAGE_NAME_PREFIX = "IMG"; + + private static final String GRAPHIC_NAME_PREFIX = "GRA"; + + private static final String BARCODE_NAME_PREFIX = "BAR"; + +// private static final String OTHER_NAME_PREFIX = "OTH"; + + private static final String OBJECT_CONTAINER_NAME_PREFIX = "OC"; + + private static final String RESOURCE_NAME_PREFIX = "RES"; + + private static final String RESOURCE_GROUP_NAME_PREFIX = "RG"; + + private static final String PAGE_GROUP_NAME_PREFIX = "PGP"; + + private static final String PAGE_NAME_PREFIX = "PGN"; + + private static final String OVERLAY_NAME_PREFIX = "OVL"; + + private static final String PRESENTATION_TEXT_NAME_PREFIX = "PT"; + + private static final String DOCUMENT_NAME_PREFIX = "DOC"; + + private static final String IM_IMAGE_NAME_PREFIX = "IMIMG"; + + private static final String IMAGE_SEGMENT_NAME_PREFIX = "IS"; + + + /** the page group count */ + private int pageGroupCount = 0; + + /** the page count */ + private int pageCount = 0; + + /** the image count */ + private int imageCount = 0; + + /** the im image count */ + private int imImageCount = 0; + + /** the image segment count */ + private int imageSegmentCount = 0; + + /** the graphic count */ + private int graphicCount = 0; + + /** the object container count */ + private int objectContainerCount = 0; + + /** the resource count */ + private int resourceCount = 0; + + /** the resource group count */ + private int resourceGroupCount = 0; + + /** the overlay count */ + private int overlayCount = 0; + + /** the presentation text object count */ + private int textObjectCount = 0; + + /** the active environment group count */ + private int activeEnvironmentGroupCount = 0; + + /** the document count */ + private int documentCount = 0; + + /** the object environment group count */ + private int objectEnvironmentGroupCount = 0; + + /** + * Main constructor + */ + public Factory() { + } + + /** + * Creates a new IOCA {@link ImageObject} + * + * @return a new {@link ImageObject} + */ + public ImageObject createImageObject() { + String name = IMAGE_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++imageCount), '0', 5); + ImageObject imageObject = new ImageObject(this, name); + return imageObject; + } + + /** + * Creates an IOCA {@link IMImageObject} + * + * @return a new {@link IMImageObject} + */ + public IMImageObject createIMImageObject() { + String name = IM_IMAGE_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++imImageCount), '0', 3); + IMImageObject imImageObject = new IMImageObject(name); + return imImageObject; + } + + /** + * Creates a new GOCA {@link GraphicsObject} + * + * @return a new {@link GraphicsObject} + */ + public GraphicsObject createGraphic() { + String name = GRAPHIC_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++graphicCount), '0', 5); + GraphicsObject graphicsObj = new GraphicsObject(this, name); + return graphicsObj; + } + + /** + * Creates a new MO:DCA {@link ObjectContainer} + * + * @return a new {@link ObjectContainer} + */ + public ObjectContainer createObjectContainer() { + String name = OBJECT_CONTAINER_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++objectContainerCount), '0', 6); + return new ObjectContainer(this, name); + } + + /** + * Creates a new MO:DCA {@link ResourceObject} + * + * @param resourceName the resource object name + * @return a new {@link ResourceObject} + */ + public ResourceObject createResource(String resourceName) { + return new ResourceObject(resourceName); + } + + /** + * Creates a new MO:DCA {@link ResourceObject} + * + * @return a new {@link ResourceObject} + */ + public ResourceObject createResource() { + String name = RESOURCE_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++resourceCount), '0', 5); + return createResource(name); + } + + /** + * Creates a new MO:DCA {@link PageGroup} + * + * @return a new {@link PageGroup} + */ + public PageGroup createPageGroup() { + String name = PAGE_GROUP_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++pageGroupCount), '0', 5); + return new PageGroup(this, name); + } + + /** + * Creates a new MO:DCA {@link ActiveEnvironmentGroup} + * + * @param width the page width + * @param height the page height + * @param widthRes the page width resolution + * @param heightRes the page height resolution + * @return a new {@link ActiveEnvironmentGroup} + */ + public ActiveEnvironmentGroup createActiveEnvironmentGroup( + int width, int height, int widthRes, int heightRes) { + String name = ACTIVE_ENVIRONMENT_GROUP_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++activeEnvironmentGroupCount ), '0', 5); + return new ActiveEnvironmentGroup(this, name, width, height, widthRes, heightRes); + } + + /** + * Creates a new MO:DCA {@link ResourceGroup} + * + * @return a new {@link ResourceGroup} + */ + public ResourceGroup createResourceGroup() { + String name = RESOURCE_GROUP_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6); + return new ResourceGroup(name); + } + + /** + * Creates a new MO:DCA {@link StreamedResourceGroup} + * + * @param os the outputstream of the streamed resource group + * @return a new {@link StreamedResourceGroup} + */ + public StreamedResourceGroup createStreamedResourceGroup(OutputStream os) { + String name = RESOURCE_GROUP_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6); + return new StreamedResourceGroup(name, os); + } + + /** + * Creates a new MO:DCA {@link PageObject}. + * + * @param pageWidth + * the width of the page + * @param pageHeight + * the height of the page + * @param pageRotation + * the rotation of the page + * @param pageWidthRes + * the width resolution of the page + * @param pageHeightRes + * the height resolution of the page + * + * @return a new {@link PageObject} + */ + public PageObject createPage(int pageWidth, int pageHeight, int pageRotation, + int pageWidthRes, int pageHeightRes) { + String pageName = PAGE_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++pageCount), '0', 5); + return new PageObject(this, pageName, pageWidth, pageHeight, + pageRotation, pageWidthRes, pageHeightRes); + } + + + /** + * Creates a new MO:DCA {@link PresentationTextObject}. + * + * @return a new {@link PresentationTextObject} + */ + public PresentationTextObject createPresentationTextObject() { + String textObjectName = PRESENTATION_TEXT_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++textObjectCount), '0', 6); + return new PresentationTextObject(textObjectName); + } + + + /** + * Creates a new MO:DCA {@link Overlay}. + * + * @param width + * the width of the overlay + * @param height + * the height of the overlay + * @param widthRes + * the width resolution of the overlay + * @param heightRes + * the height resolution of the overlay + * @param overlayRotation + * the rotation of the overlay + * + * @return a new {@link Overlay}. + */ + public Overlay createOverlay(int width, int height, + int widthRes, int heightRes, int overlayRotation) { + String overlayName = OVERLAY_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++overlayCount), '0', 5); + Overlay overlay = new Overlay(this, overlayName, width, height, + overlayRotation, widthRes, heightRes); + return overlay; + } + + /** + * Creates a MO:DCA {@link Document} + * + * @return a new {@link Document} + */ + public Document createDocument() { + String documentName = DOCUMENT_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++documentCount), '0', 5); + Document document = new Document(this, documentName); + return document; + } + + /** + * Creates a MO:DCA {@link MapCodedFont} + * + * @return a new {@link MapCodedFont} + */ + public MapCodedFont createMapCodedFont() { + MapCodedFont mapCodedFont = new MapCodedFont(); + return mapCodedFont; + } + + /** + * Creates a MO:DCA {@link IncludePageSegment} + * + * @param name the page segment name + * @param x the x coordinate + * @param y the y coordinate + * + * @return a new {@link IncludePageSegment} + */ + public IncludePageSegment createIncludePageSegment(String name, int x, int y) { + IncludePageSegment includePageSegment = new IncludePageSegment(name, x, y); + return includePageSegment; + } + + /** + * Creates a MO:DCA {@link IncludeObject} + * + * @param name the name of this include object + * @return a new {@link IncludeObject} + */ + public IncludeObject createInclude(String name) { + IncludeObject includeObject = new IncludeObject(name); + return includeObject; + } + + /** + * Creates a MO:DCA {@link TagLogicalElement} + * + * @param name name of the element + * @param value value of the element + * @return a new {@link TagLogicalElement} + */ + public TagLogicalElement createTagLogicalElement(String name, String value) { + TagLogicalElement tle = new TagLogicalElement(name, value); + return tle; + } + + /** + * Creates an {@link DataStream} + * + * @param outputStream an outputstream to write to + * @return a new {@link DataStream} + */ + public DataStream createDataStream(OutputStream outputStream) { + DataStream dataStream = new DataStream(this, outputStream); + return dataStream; + } + + /** + * Creates a new MO:DCA {@link PageDescriptor} + * + * @param width the page width. + * @param height the page height. + * @param widthRes the page width resolution. + * @param heightRes the page height resolution. + * @return a new {@link PageDescriptor} + */ + public PageDescriptor createPageDescriptor(int width, int height, int widthRes, int heightRes) { + PageDescriptor pageDescriptor = new PageDescriptor(width, height, widthRes, heightRes); + return pageDescriptor; + } + + /** + * Returns a new MO:DCA {@link ObjectEnvironmentGroup} + * + * @return a new {@link ObjectEnvironmentGroup} + */ + public ObjectEnvironmentGroup createObjectEnvironmentGroup() { + String oegName = OBJECT_ENVIRONMENT_GROUP_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++objectEnvironmentGroupCount), '0', 5); + ObjectEnvironmentGroup objectEnvironmentGroup = new ObjectEnvironmentGroup(this, oegName); + return objectEnvironmentGroup; + } + + /** + * Creates a new GOCA {@link GraphicsData} + * + * @return a new {@link GraphicsData} + */ + public GraphicsData createGraphicsData() { + GraphicsData graphicsData = new GraphicsData(); + return graphicsData; + } + + /** + * Creates a new {@link ObjectAreaDescriptor} + * + * @param width the object width. + * @param height the object height. + * @param widthRes the object width resolution. + * @param heightRes the object height resolution. + * @return a new {@link ObjectAreaDescriptor} + */ + public ObjectAreaDescriptor createObjectAreaDescriptor( + int width, int height, int widthRes, int heightRes) { + ObjectAreaDescriptor objectAreaDescriptor + = new ObjectAreaDescriptor(width, height, widthRes, heightRes); + return objectAreaDescriptor; + } + + /** + * Creates a new {@link ObjectAreaPosition} + * + * @param x The x coordinate. + * @param y The y coordinate. + * @param rotation The coordinate system rotation (must be 0, 90, 180, 270). + * @return a new {@link ObjectAreaPosition} + */ + public ObjectAreaPosition createObjectAreaPosition(int x, int y, + int rotation) { + ObjectAreaPosition objectAreaPosition = new ObjectAreaPosition( + x, y, rotation); + return objectAreaPosition; + } + + /** + * Creates a new {@link ImageDataDescriptor} + * + * @param width the image width + * @param height the image height + * @param widthRes the x resolution of the image + * @param heightRes the y resolution of the image + * @return a new {@link ImageDataDescriptor} + */ + public ImageDataDescriptor createImageDataDescriptor( + int width, int height, int widthRes, int heightRes) { + ImageDataDescriptor imageDataDescriptor = new ImageDataDescriptor( + width, height, widthRes, heightRes); + return imageDataDescriptor; + } + + /** + * Creates a new GOCA {@link GraphicsDataDescriptor} + * + * @param xlwind the left edge of the graphics window + * @param xrwind the right edge of the graphics window + * @param ybwind the top edge of the graphics window + * @param ytwind the bottom edge of the graphics window + * @param widthRes the x resolution of the graphics window + * @param heightRes the y resolution of the graphics window + * @return a new {@link GraphicsDataDescriptor} + */ + public GraphicsDataDescriptor createGraphicsDataDescriptor( + int xlwind, int xrwind, int ybwind, int ytwind, int widthRes, int heightRes) { + GraphicsDataDescriptor graphicsDataDescriptor = new GraphicsDataDescriptor( + xlwind, xrwind, ybwind, ytwind, widthRes, heightRes); + return graphicsDataDescriptor; + } + + /** + * Creates a new MO:DCA {@link ContainerDataDescriptor} + * + * @param width the container data width + * @param height the container data height + * @param widthRes the container data width resolution + * @param heightRes the container data height resolution + * @return a new {@link ContainerDataDescriptor} + */ + public ContainerDataDescriptor createContainerDataDescriptor( + int width, int height, int widthRes, int heightRes) { + ContainerDataDescriptor containerDataDescriptor + = new ContainerDataDescriptor(width, height, widthRes, heightRes); + return containerDataDescriptor; + } + + /** + * Creates a new IOCA {@link ImageSegment} + * + * @return a new {@link ImageSegment} + */ + public ImageSegment createImageSegment() { + String name = IMAGE_SEGMENT_NAME_PREFIX + + StringUtils.lpad(String.valueOf(++imageSegmentCount), '0', 2); + ImageSegment imageSegment = new ImageSegment(this, name); + return imageSegment; + } + + /** + * Creates an new IOCA {@link ImageContent} + * + * @return an {@link ImageContent} + */ + public ImageContent createImageContent() { + ImageContent imageContent = new ImageContent(); + return imageContent; + } + + + /** + * Creates a new IOCA {@link ImageRasterData} + * + * @param rasterData raster data + * @return a new {@link ImageRasterData} + */ + public ImageRasterData createImageRasterData(byte[] rasterData) { + ImageRasterData imageRasterData = new ImageRasterData(rasterData); + return imageRasterData; + } + +} diff --git a/src/java/org/apache/fop/render/afp/modca/GraphicsDataDescriptor.java b/src/java/org/apache/fop/render/afp/modca/GraphicsDataDescriptor.java index 53ebe233f..e2b18cc3e 100644 --- a/src/java/org/apache/fop/render/afp/modca/GraphicsDataDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/GraphicsDataDescriptor.java @@ -5,9 +5,9 @@ * 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. @@ -27,59 +27,64 @@ import org.apache.fop.render.afp.tools.BinaryUtils; /** * GOCA Graphics Data Descriptor */ -public class GraphicsDataDescriptor extends AbstractAFPObject { +public class GraphicsDataDescriptor extends AbstractDescriptor { + + private final int xlwind; + + private final int xrwind; + + private final int ybwind; + + private final int ytwind; - private int xlwind; - private int xrwind; - private int ybwind; - private int ytwind; - private int xresol; - private int yresol; - /** * Main constructor - * @param xresol the x resolution of the graphics window - * @param yresol the y resolution of the graphics window - * @param xlwind the left edge of the graphics window - * @param xrwind the right edge of the graphics window - * @param ybwind the top edge of the graphics window - * @param ytwind the bottom edge of the graphics window + * + * @param xlwind + * the left edge of the graphics window + * @param xrwind + * the right edge of the graphics window + * @param ybwind + * the top edge of the graphics window + * @param ytwind + * the bottom edge of the graphics window + * @param widthRes + * the width resolution of the graphics window + * @param heightRes + * the height resolution of the graphics window */ - protected GraphicsDataDescriptor(int xresol, int yresol, - int xlwind, int xrwind, int ybwind, int ytwind) { - this.xresol = xresol; - this.yresol = yresol; + protected GraphicsDataDescriptor(int xlwind, int xrwind, int ybwind, + int ytwind, int widthRes, int heightRes) { this.xlwind = xlwind; this.xrwind = xrwind; this.ybwind = ybwind; this.ytwind = ytwind; - } + super.widthRes = widthRes; + super.heightRes = heightRes; + } - private static final int ABS = 2; - private static final int IMGRES = 8; + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + byte[] headerData = new byte[9]; + copySF(headerData, Type.DESCRIPTOR, Category.GRAPHICS); + byte[] drawingOrderSubsetData = getDrawingOrderSubset(); + byte[] windowSpecificationData = getWindowSpecification(); + byte[] len = BinaryUtils.convert( + 8 + drawingOrderSubsetData.length + windowSpecificationData.length, 2); + headerData[1] = len[0]; + headerData[2] = len[1]; + os.write(headerData); + os.write(drawingOrderSubsetData); + os.write(windowSpecificationData); + } /** - * {@inheritDoc} + * Returns the drawing order subset data + * + * @return the drawing order subset data */ - public void write(OutputStream os) throws IOException { - byte[] xreswind = BinaryUtils.convert(xresol * 10, 2); - byte[] yreswind = BinaryUtils.convert(yresol * 10, 2); - byte[] xlcoord = BinaryUtils.convert(xlwind, 2); - byte[] xrcoord = BinaryUtils.convert(xrwind, 2); - byte[] xbcoord = BinaryUtils.convert(ybwind, 2); - byte[] ytcoord = BinaryUtils.convert(ytwind, 2); - byte[] imxyres = xreswind; - byte[] data = new byte[] { - 0x5A, - 0x00, - 0x25, - (byte) 0xD3, - (byte) 0xA6, - (byte) 0xBB, - 0x00, // Flags - 0x00, // Reserved - 0x00, // Reserved - + private byte[] getDrawingOrderSubset() { + final byte[] data = new byte[] { // Drawing order subset (byte) 0xF7, 7, // LENGTH @@ -89,21 +94,41 @@ public class GraphicsDataDescriptor extends AbstractAFPObject { 0x02, // SUBLEV 0x00, // VERSION 0 0x01, // LENGTH (of following field) - 0x00, // GEOM + 0x00 // GEOM + }; + return data; + } + + private static final int ABS = 2; + private static final int IMGRES = 8; + + /** + * Returns the window specification data + * + * @return the window specification data + */ + private byte[] getWindowSpecification() { + byte[] xlcoord = BinaryUtils.convert(xlwind, 2); + byte[] xrcoord = BinaryUtils.convert(xrwind, 2); + byte[] xbcoord = BinaryUtils.convert(ybwind, 2); + byte[] ytcoord = BinaryUtils.convert(ytwind, 2); + byte[] xResol = BinaryUtils.convert(widthRes * 10, 2); + byte[] yResol = BinaryUtils.convert(heightRes * 10, 2); + byte[] imxyres = xResol; - // Window specification - (byte) 0xF6, - 18, // LENGTH + final byte[] data = new byte[] { + // Window specification + (byte) 0xF6, 18, // LENGTH (ABS + IMGRES), // FLAGS (ABS) 0x00, // reserved (must be zero) 0x00, // CFORMAT (coordinate format - 16bit high byte first signed) 0x00, // UBASE (unit base - ten inches) - xreswind[0], // XRESOL - xreswind[1], - yreswind[0], // YRESOL - yreswind[1], + xResol[0], // XRESOL + xResol[1], + yResol[0], // YRESOL + yResol[1], imxyres[0], // IMXYRES (Number of image points per ten inches - imxyres[1], // in X and Y directions) + imxyres[1], // in X and Y directions) xlcoord[0], // XLWIND xlcoord[1], xrcoord[0], // XRWIND @@ -113,6 +138,6 @@ public class GraphicsDataDescriptor extends AbstractAFPObject { ytcoord[0], // YTWIND ytcoord[1] }; - os.write(data); + return data; } } diff --git a/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java index ccf05aa19..c5be86023 100644 --- a/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java +++ b/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java @@ -5,9 +5,9 @@ * 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. @@ -22,15 +22,14 @@ package org.apache.fop.render.afp.modca; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; +import java.util.List; -import org.apache.fop.render.afp.ObjectAreaInfo; +import org.apache.fop.render.afp.AFPDataObjectInfo; +import org.apache.fop.render.afp.AFPObjectAreaInfo; import org.apache.fop.render.afp.goca.GraphicsBox; import org.apache.fop.render.afp.goca.GraphicsData; import org.apache.fop.render.afp.goca.GraphicsFillet; import org.apache.fop.render.afp.goca.GraphicsFullArc; -import org.apache.fop.render.afp.goca.GraphicsImageBegin; -import org.apache.fop.render.afp.goca.GraphicsImageData; -import org.apache.fop.render.afp.goca.GraphicsImageEnd; import org.apache.fop.render.afp.goca.GraphicsLine; import org.apache.fop.render.afp.goca.GraphicsSetArcParameters; import org.apache.fop.render.afp.goca.GraphicsSetCharacterSet; @@ -43,52 +42,43 @@ import org.apache.fop.render.afp.goca.GraphicsString; /** * Top-level GOCA graphics object. - * + * * Acts as container and factory of all other graphic objects */ public class GraphicsObject extends AbstractDataObject { - + /** The graphics data */ private GraphicsData graphicsData = null; + /** list of objects contained within this container */ + protected List/*<PreparedAFPObject>*/ objects + = new java.util.ArrayList/*<PreparedAFPObject>*/(); + /** * Default constructor - * + * + * @param factory the object factory * @param name the name of graphics object */ - public GraphicsObject(String name) { - super(name); - } - - /** {@inheritDoc} */ - public void setViewport(ObjectAreaInfo objectAreaInfo) { - super.setViewport(objectAreaInfo); - getObjectEnvironmentGroup().setGraphicsData( - objectAreaInfo.getWidthRes(), - objectAreaInfo.getHeightRes(), - 0, - objectAreaInfo.getX() + objectAreaInfo.getWidth(), - 0, - objectAreaInfo.getY() + objectAreaInfo.getHeight()); + public GraphicsObject(Factory factory, String name) { + super(factory, name); } /** {@inheritDoc} */ - protected byte getCategoryCode() { - return (byte)0xBB; - } + public void setViewport(AFPDataObjectInfo dataObjectInfo) { + super.setViewport(dataObjectInfo); - /** {@inheritDoc} */ - protected void writeStart(OutputStream os) throws IOException { - byte[] data = new byte[17]; - copySF(data, Type.BEGIN, Category.GRAPHICS); - os.write(data); - } + AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); + GraphicsDataDescriptor graphicsDataDescriptor + = factory.createGraphicsDataDescriptor( + 0, + objectAreaInfo.getWidth(), + 0, + objectAreaInfo.getHeight(), + objectAreaInfo.getWidthRes(), + objectAreaInfo.getHeightRes()); - /** {@inheritDoc} */ - protected void writeEnd(OutputStream os) throws IOException { - byte[] data = new byte[17]; - copySF(data, Type.END, Category.GRAPHICS); - os.write(data); + getObjectEnvironmentGroup().setDataDescriptor(graphicsDataDescriptor); } /** {@inheritDoc} */ @@ -101,10 +91,10 @@ public class GraphicsObject extends AbstractDataObject { graphicsData.addObject(drawingOrder); return drawingOrder; } - + /** * Gets the current graphics data, creating a new one if necessary - * + * * @return the current graphics data */ private GraphicsData getData() { @@ -113,21 +103,21 @@ public class GraphicsObject extends AbstractDataObject { } return this.graphicsData; } - + /** * Creates a new graphics data - * + * * @return a newly created graphics data */ private GraphicsData newData() { - this.graphicsData = new GraphicsData(); - super.addObject(graphicsData); + this.graphicsData = factory.createGraphicsData(); + objects.add(graphicsData); return graphicsData; } - + /** * Sets the current color - * + * * @param col the active color to use */ public void setColor(Color col) { @@ -136,7 +126,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Sets the current position - * + * * @param coords the x and y coordinates of the current position */ public void setCurrentPosition(int[] coords) { @@ -145,7 +135,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Sets the line width - * + * * @param multiplier the line width multiplier */ public void setLineWidth(int multiplier) { @@ -155,17 +145,17 @@ public class GraphicsObject extends AbstractDataObject { /** * Sets the line type - * + * * @param type the line type */ public void setLineType(byte type) { GraphicsSetLineType lt = new GraphicsSetLineType(type); addObject(lt); - } + } /** * Sets whether to fill the next shape - * + * * @param fill whether to fill the next shape */ public void setFill(boolean fill) { @@ -175,10 +165,10 @@ public class GraphicsObject extends AbstractDataObject { ); addObject(pat); } - + /** * Sets the character set to use - * + * * @param fontReference the character set (font) reference */ public void setCharacterSet(int fontReference) { @@ -187,7 +177,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Adds a line at the given x/y coordinates - * + * * @param coords the x/y coordinates (can be a series) */ public void addLine(int[] coords) { @@ -196,7 +186,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Adds a box at the given coordinates - * + * * @param coords the x/y coordinates */ public void addBox(int[] coords) { @@ -205,7 +195,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Adds a fillet (curve) at the given coordinates - * + * * @param coords the x/y coordinates */ public void addFillet(int[] coords) { @@ -214,7 +204,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Sets the arc parameters - * + * * @param xmaj the maximum value of the x coordinate * @param ymin the minimum value of the y coordinate * @param xmin the minimum value of the x coordinate @@ -226,7 +216,7 @@ public class GraphicsObject extends AbstractDataObject { /** * Adds an arc - * + * * @param x the x coordinate * @param y the y coordinate * @param mh the integer portion of the multiplier @@ -236,28 +226,22 @@ public class GraphicsObject extends AbstractDataObject { addObject(new GraphicsFullArc(x, y, mh, mhr)); } - /** - * Adds an image - * - * @param x the x coordinate - * @param y the y coordinate - * @param width the image width - * @param height the image height - * @param imgData the image data - */ - public void addImage(int x, int y, int width, int height, byte[] imgData) { - addObject(new GraphicsImageBegin(x, y, width, height)); - for (int startIndex = 0; - startIndex <= imgData.length; - startIndex += GraphicsImageData.MAX_DATA_LEN) { - addObject(new GraphicsImageData(imgData, startIndex)); - } - addObject(new GraphicsImageEnd()); - } +// /** +// * Adds an image +// * +// * @param x the x coordinate +// * @param y the y coordinate +// * @param width the image width +// * @param height the image height +// * @param imgData the image data +// */ +// public void addImage(int x, int y, int width, int height, byte[] imgData) { +// addObject(new GraphicsImage(x, y, width, height, imgData)); +// } /** * Adds a string - * + * * @param str the string * @param x the x coordinate * @param y the y coordinate @@ -265,7 +249,7 @@ public class GraphicsObject extends AbstractDataObject { public void addString(String str, int x, int y) { addObject(new GraphicsString(str, x, y)); } - + /** * Begins a graphics area (start of fill) */ @@ -284,7 +268,7 @@ public class GraphicsObject extends AbstractDataObject { graphicsData.endArea(); } } - + /** {@inheritDoc} */ public String toString() { return "GraphicsObject: " + getName(); @@ -296,4 +280,24 @@ public class GraphicsObject extends AbstractDataObject { public void newSegment() { getData().newSegment(); } + + /** {@inheritDoc} */ + protected void writeStart(OutputStream os) throws IOException { + byte[] data = new byte[17]; + copySF(data, Type.BEGIN, Category.GRAPHICS); + os.write(data); + } + + /** {@inheritDoc} */ + protected void writeContent(OutputStream os) throws IOException { + super.writeContent(os); + super.writeObjects(objects, os); + } + + /** {@inheritDoc} */ + protected void writeEnd(OutputStream os) throws IOException { + byte[] data = new byte[17]; + copySF(data, Type.END, Category.GRAPHICS); + 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 index 3af8b5c28..63fff8cdc 100644 --- a/src/java/org/apache/fop/render/afp/modca/IMImageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/IMImageObject.java @@ -22,6 +22,11 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; +import org.apache.fop.render.afp.ioca.ImageCellPosition; +import org.apache.fop.render.afp.ioca.ImageInputDescriptor; +import org.apache.fop.render.afp.ioca.ImageOutputControl; +import org.apache.fop.render.afp.ioca.ImageRasterData; + /** * 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 @@ -60,7 +65,7 @@ public class IMImageObject extends AbstractNamedAFPObject { /** * 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) { @@ -69,7 +74,7 @@ public class IMImageObject extends AbstractNamedAFPObject { /** * Sets the ImageOutputControl. - * + * * @param imageOutputControl The imageOutputControl to set */ public void setImageOutputControl(ImageOutputControl imageOutputControl) { @@ -78,7 +83,7 @@ public class IMImageObject extends AbstractNamedAFPObject { /** * Sets the ImageCellPosition. - * + * * @param imageCellPosition The imageCellPosition to set */ public void setImageCellPosition(ImageCellPosition imageCellPosition) { @@ -87,7 +92,7 @@ public class IMImageObject extends AbstractNamedAFPObject { /** * Sets the ImageInputDescriptor. - * + * * @param imageInputDescriptor The imageInputDescriptor to set */ public void setImageInputDescriptor(ImageInputDescriptor imageInputDescriptor) { @@ -96,7 +101,7 @@ public class IMImageObject extends AbstractNamedAFPObject { /** * Sets the ImageRastorData. - * + * * @param imageRasterData The imageRasterData to set */ public void setImageRasterData(ImageRasterData imageRasterData) { @@ -107,16 +112,16 @@ public class IMImageObject extends AbstractNamedAFPObject { protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); if (imageOutputControl != null) { - imageOutputControl.write(os); + imageOutputControl.writeToStream(os); } if (imageInputDescriptor != null) { - imageInputDescriptor.write(os); + imageInputDescriptor.writeToStream(os); } if (imageCellPosition != null) { - imageCellPosition.write(os); + imageCellPosition.writeToStream(os); } if (imageRasterData != null) { - imageRasterData.write(os); + imageRasterData.writeToStream(os); } } diff --git a/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java index 243765727..430f6590c 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/ImageDataDescriptor.java @@ -24,61 +24,32 @@ import java.io.OutputStream; import org.apache.fop.render.afp.tools.BinaryUtils; /** + * ImageDataDescriptor */ -public class ImageDataDescriptor extends AbstractAFPObject { +public class ImageDataDescriptor extends AbstractDescriptor { - private int widthRes = 0; - private int heightRes = 0; - private int width = 0; - private int height = 0; - /** * Constructor for a ImageDataDescriptor for the specified * resolution, width and height. - * - * @param widthRes The horizontal resolution of the image. - * @param heightRes The vertical resolution of the image. + * * @param width The width of the image. * @param height The height of the height. + * @param widthRes The horizontal resolution of the image. + * @param heightRes The vertical resolution of the image. */ - public ImageDataDescriptor(int widthRes, int heightRes, int width, int height) { - this.widthRes = widthRes; - this.heightRes = heightRes; - this.width = width; - this.height = height; + public ImageDataDescriptor(int width, int height, int widthRes, int heightRes) { + super(width, height, widthRes, heightRes); } /** {@inheritDoc} */ - public void write(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 - }; + public void writeToStream(OutputStream os) throws IOException { + byte[] data = new byte[22]; + copySF(data, Type.DESCRIPTOR, Category.IMAGE); - byte[] l = BinaryUtils.convert(data.length - 1, 2); - data[1] = l[0]; - data[2] = l[1]; + // SF length + byte[] len = BinaryUtils.convert(data.length - 1, 2); + data[1] = len[0]; + data[2] = len[1]; byte[] x = BinaryUtils.convert(widthRes, 2); data[10] = x[0]; @@ -96,6 +67,11 @@ public class ImageDataDescriptor extends AbstractAFPObject { data[16] = h[0]; data[17] = h[1]; + data[18] = (byte)0xF7; // ID = Set IOCA Function Set + data[19] = 0x02; // Length + data[20] = 0x01; // Category = Function set identifier + data[21] = 0x0B; // FCNSET = IOCA FS 11 + os.write(data); } } diff --git a/src/java/org/apache/fop/render/afp/modca/ImageObject.java b/src/java/org/apache/fop/render/afp/modca/ImageObject.java index 04a019f5d..1e62446e9 100644 --- a/src/java/org/apache/fop/render/afp/modca/ImageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/ImageObject.java @@ -19,121 +19,105 @@ 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; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.fop.render.afp.AFPDataObjectInfo; +import org.apache.fop.render.afp.AFPImageObjectInfo; +import org.apache.fop.render.afp.AFPObjectAreaInfo; +import org.apache.fop.render.afp.ioca.ImageSegment; /** * An IOCA Image Data Object */ public class ImageObject extends AbstractDataObject { - /** - * The image segment - */ + private static final int MAX_DATA_LEN = 32759; + + /** 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. + * @param factory the resource manager */ - public ImageObject(String name) { - super(name); + public ImageObject(Factory factory, String name) { + super(factory, name); } - /** - * 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) { - getObjectEnvironmentGroup().setImageData(xresol, yresol, width, height); + private ImageSegment getImageSegment() { if (imageSegment == null) { - imageSegment = new ImageSegment(); + this.imageSegment = factory.createImageSegment(); } - imageSegment.setImageSize(xresol, yresol, width, height); + return imageSegment; + } + + /** {@inheritDoc} */ + public void setViewport(AFPDataObjectInfo dataObjectInfo) { + super.setViewport(dataObjectInfo); + + AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)dataObjectInfo; + int dataWidth = imageObjectInfo.getDataWidth(); + int dataHeight = imageObjectInfo.getDataHeight(); + + AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); + int widthRes = objectAreaInfo.getWidthRes(); + int heightRes = objectAreaInfo.getHeightRes(); + + ImageDataDescriptor imageDataDescriptor + = factory.createImageDataDescriptor(dataWidth, dataHeight, widthRes, heightRes); + getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor); + + getImageSegment().setImageSize(dataWidth, dataHeight, widthRes, heightRes); } /** * Sets the image encoding. - * + * * @param encoding The image encoding. */ - public void setImageEncoding(byte encoding) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageEncoding(encoding); + public void setEncoding(byte encoding) { + getImageSegment().setEncoding(encoding); } /** * Sets the image compression. - * + * * @param compression The image compression. */ - public void setImageCompression(byte compression) { - if (imageSegment == null) { - imageSegment = new ImageSegment(); - } - imageSegment.setImageCompression(compression); + public void setCompression(byte compression) { + getImageSegment().setCompression(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); + public void setIDESize(byte size) { + getImageSegment().setIDESize(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); + public void setIDEColorModel(byte colorModel) { + getImageSegment().setIDEColorModel(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); - } - - /** - * Helper method to return the start of the image object. - * - * @param len the length of this ipd start - * @return byte[] The data stream. + * + * @param data the image data */ - private byte[] getImageData(int len) { - byte[] data = new byte[9]; - copySF(data, SF_CLASS, Type.DATA, Category.IMAGE); - byte[] l = BinaryUtils.convert(len + 8, 2); - data[1] = l[0]; - data[2] = l[1]; - return data; + public void setData(byte[] data) { + getImageSegment().setData(data); } /** {@inheritDoc} */ @@ -146,17 +130,17 @@ public class ImageObject extends AbstractDataObject { /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); + if (imageSegment != null) { + // TODO save memory! ByteArrayOutputStream baos = new ByteArrayOutputStream(); - imageSegment.write(baos); - byte[] b = baos.toByteArray(); - int off = 0; - while (off < b.length) { - int len = Math.min(30000, b.length - off); - os.write(getImageData(len)); - os.write(b, off, len); - off += len; - } + imageSegment.writeToStream(baos); + byte[] data = baos.toByteArray(); + + final byte[] dataHeader = new byte[9]; + copySF(dataHeader, SF_CLASS, Type.DATA, Category.IMAGE); + final int lengthOffset = 1; + writeChunksToStream(data, dataHeader, lengthOffset, MAX_DATA_LEN, os); } } diff --git a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java b/src/java/org/apache/fop/render/afp/modca/IncludeObject.java index de3efd977..fde387d26 100644 --- a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java +++ b/src/java/org/apache/fop/render/afp/modca/IncludeObject.java @@ -58,16 +58,16 @@ public class IncludeObject extends AbstractNamedAFPObject { * the included object is of type barcode */ public static final byte TYPE_BARCODE = (byte)0xEB; - + /** * the included object is of type image */ public static final byte TYPE_IMAGE = (byte)0xFB; - + /** * The object type (default is other) */ - private byte dataObjectType = TYPE_OTHER; + private byte objectType = TYPE_OTHER; /** * The orientation on the include object @@ -75,13 +75,13 @@ public class IncludeObject extends AbstractNamedAFPObject { private int orientation = 0; /** - * The X-axis origin of the object area + * The X-axis origin of the object area */ - private int xOffset = 0; - + private int xOffset = 0; + /** - * The Y-axis origin of the object area - */ + * The Y-axis origin of the object area + */ private int yOffset = 0; /** @@ -93,7 +93,7 @@ public class IncludeObject extends AbstractNamedAFPObject { * The Y-axis origin defined in the object */ private int yContentOffset = 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 @@ -122,8 +122,8 @@ public class IncludeObject extends AbstractNamedAFPObject { } /** - * Sets the x and y offset to the origin in the object area - * + * Sets the x and y offset to the origin in the object area + * * @param x the X-axis origin of the object area * @param y the Y-axis origin of the object area */ @@ -131,10 +131,10 @@ public class IncludeObject extends AbstractNamedAFPObject { this.xOffset = x; this.yOffset = y; } - + /** * Sets the x and y offset of the content area to the object area - * + * * @param x the X-axis origin defined in the object * @param y the Y-axis origin defined in the object */ @@ -142,18 +142,18 @@ public class IncludeObject extends AbstractNamedAFPObject { this.xContentOffset = x; this.yContentOffset = y; } - + /** * Sets the data object type - * + * * @param type the data object type */ - public void setDataObjectType(byte type) { - this.dataObjectType = type; + public void setObjectType(byte type) { + this.objectType = type; } - + /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[36]; super.copySF(data, Type.INCLUDE, Category.DATA_RESOURCE); @@ -163,18 +163,18 @@ public class IncludeObject extends AbstractNamedAFPObject { data[2] = len[1]; data[17] = 0x00; // reserved - data[18] = dataObjectType; + data[18] = objectType; //XoaOset (object area) if (xOffset >= -1) { byte[] x = BinaryUtils.convert(xOffset, 3); data[19] = x[0]; data[20] = x[1]; - data[21] = x[2]; + data[21] = x[2]; } else { data[19] = (byte)0xFF; data[20] = (byte)0xFF; - data[21] = (byte)0xFF; + data[21] = (byte)0xFF; } // YoaOset (object area) @@ -182,20 +182,21 @@ public class IncludeObject extends AbstractNamedAFPObject { byte[] y = BinaryUtils.convert(yOffset, 3); data[22] = y[0]; data[23] = y[1]; - data[24] = y[2]; + data[24] = y[2]; } else { data[22] = (byte)0xFF; data[23] = (byte)0xFF; - data[24] = (byte)0xFF; + data[24] = (byte)0xFF; } + // XoaOrent/YoaOrent switch (orientation) { case -1: // use x/y axis orientation defined in object data[25] = (byte)0xFF; // x axis rotation data[26] = (byte)0xFF; // data[27] = (byte)0xFF; // y axis rotation data[28] = (byte)0xFF; - break; + break; case 90: data[25] = 0x2D; data[26] = 0x00; @@ -227,7 +228,7 @@ public class IncludeObject extends AbstractNamedAFPObject { byte[] y = BinaryUtils.convert(xContentOffset, 3); data[29] = y[0]; data[30] = y[1]; - data[31] = y[2]; + data[31] = y[2]; } else { data[29] = (byte)0xFF; data[30] = (byte)0xFF; @@ -239,7 +240,7 @@ public class IncludeObject extends AbstractNamedAFPObject { byte[] y = BinaryUtils.convert(yContentOffset, 3); data[32] = y[0]; data[33] = y[1]; - data[34] = y[2]; + data[34] = y[2]; } else { data[32] = (byte)0xFF; data[33] = (byte)0xFF; @@ -249,12 +250,11 @@ public class IncludeObject extends AbstractNamedAFPObject { // Write structured field data os.write(data); - - // Write triplet for FQN internal/external object reference - byte[] tripletData = super.getTripletData(); + + // Write triplet for FQN internal/external object reference os.write(tripletData); } - + /** {@inheritDoc} */ public String toString() { return "IOB: " + this.getName(); diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java b/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java index 540ebe7df..be1ef870f 100644 --- a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java +++ b/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java @@ -87,7 +87,7 @@ public class IncludePageOverlay extends AbstractNamedAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[25]; //(9 +16) copySF(data, Type.INCLUDE, Category.PAGE_OVERLAY); diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java b/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java index b069f4f7a..a9d247553 100644 --- a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java +++ b/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java @@ -67,7 +67,7 @@ public class IncludePageSegment extends AbstractNamedAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[23]; //(9 +14) copySF(data, Type.INCLUDE, Category.PAGE_SEGMENT); diff --git a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java b/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java index fd41ce305..cee7711e6 100644 --- a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java +++ b/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java @@ -42,7 +42,7 @@ public class InvokeMediumMap extends AbstractNamedAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.MAP, Category.MEDIUM_MAP); diff --git a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java index 512e091a3..f305630bc 100644 --- a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java +++ b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java @@ -57,7 +57,7 @@ public class MapCodedFont extends AbstractStructuredAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] startData = new byte[9]; diff --git a/src/java/org/apache/fop/render/afp/modca/MapDataResource.java b/src/java/org/apache/fop/render/afp/modca/MapDataResource.java index ae9df023f..12a8c6406 100644 --- a/src/java/org/apache/fop/render/afp/modca/MapDataResource.java +++ b/src/java/org/apache/fop/render/afp/modca/MapDataResource.java @@ -5,9 +5,9 @@ * 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. @@ -22,11 +22,6 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.DataObjectInfo; -import org.apache.fop.render.afp.ResourceInfo; -import org.apache.fop.render.afp.ResourceLevel; -import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet; -import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -42,33 +37,33 @@ public class MapDataResource extends AbstractStructuredAFPObject { /** * Main constructor - * + * * @param dataObjectAccessor a data object accessor */ - public MapDataResource(DataObjectAccessor dataObjectAccessor) { - AbstractNamedAFPObject namedDataObject = dataObjectAccessor.getDataObject(); - DataObjectInfo dataObjectInfo = dataObjectAccessor.getDataObjectInfo(); - ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); - ResourceLevel resourceLevel = resourceInfo.getLevel(); - if (resourceLevel.isExternal()) { - String url = resourceLevel.getExternalFilePath(); - if (url != null) { - super.setFullyQualifiedName( - FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_EXTERNAL_RESOURCE_REF, - FullyQualifiedNameTriplet.FORMAT_CHARSTR, url); - } - } else { - String fqName = namedDataObject.getFullyQualifiedName(); - super.setFullyQualifiedName( - FullyQualifiedNameTriplet.TYPE_BEGIN_RESOURCE_OBJECT_REF, - FullyQualifiedNameTriplet.FORMAT_CHARSTR, fqName); - } - - // Set object classification - Registry.ObjectType objectType = dataObjectInfo.getObjectType(); - super.setObjectClassification( - ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT, - objectType); + public MapDataResource() { +// AbstractNamedAFPObject namedDataObject = dataObjectAccessor.getDataObject(); +// DataObjectInfo dataObjectInfo = dataObjectAccessor.getDataObjectInfo(); +// AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); +// AFPResourceLevel resourceLevel = resourceInfo.getLevel(); +// if (resourceLevel.isExternal()) { +// String url = resourceLevel.getExternalFilePath(); +// if (url != null) { +// super.setFullyQualifiedName( +// FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_EXTERNAL_RESOURCE_REF, +// FullyQualifiedNameTriplet.FORMAT_CHARSTR, url); +// } +// } else { +// String fqName = namedDataObject.getFullyQualifiedName(); +// super.setFullyQualifiedName( +// FullyQualifiedNameTriplet.TYPE_BEGIN_RESOURCE_OBJECT_REF, +// FullyQualifiedNameTriplet.FORMAT_CHARSTR, fqName); +// } +// +// // Set object classification +// Registry.ObjectType objectType = dataObjectInfo.getObjectType(); +// super.setObjectClassification( +// ObjectClassificationTriplet.CLASS_TIME_VARIANT_PRESENTATION_OBJECT, +// objectType); } /** {@inheritDoc} */ @@ -76,11 +71,11 @@ public class MapDataResource extends AbstractStructuredAFPObject { super.writeStart(os); byte[] data = new byte[9]; copySF(data, Type.MAP, Category.DATA_RESOURCE); - + byte[] len = BinaryUtils.convert(10 + getTripletDataLength(), 2); data[1] = len[0]; data[2] = len[1]; - + os.write(data); } @@ -89,7 +84,7 @@ public class MapDataResource extends AbstractStructuredAFPObject { // RGLength byte[] len = BinaryUtils.convert(2 + getTripletDataLength(), 2); os.write(len); - + super.writeTriplets(os); } } diff --git a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java index 7a5889456..3143e80a0 100644 --- a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java +++ b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java @@ -82,7 +82,7 @@ public class MapPageOverlay extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { int oLayCount = getOverlays().size(); int recordlength = oLayCount * 18; diff --git a/src/java/org/apache/fop/render/afp/modca/NoOperation.java b/src/java/org/apache/fop/render/afp/modca/NoOperation.java index 6896388ed..258fcf47d 100644 --- a/src/java/org/apache/fop/render/afp/modca/NoOperation.java +++ b/src/java/org/apache/fop/render/afp/modca/NoOperation.java @@ -61,7 +61,7 @@ public class NoOperation extends AbstractAFPObject { * @param os The outputsteam stream * @throws java.io.IOException if an I/O exception occurs during processing */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] contentData = content.getBytes(AFPConstants.EBCIDIC_ENCODING); int contentLen = contentData.length; diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java b/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java index fa257fb87..3bd271d5b 100644 --- a/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/ObjectAreaDescriptor.java @@ -19,14 +19,14 @@ 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.modca.triplets.DescriptorPositionTriplet; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.fop.render.afp.modca.triplets.MeasurementUnitsTriplet; import org.apache.fop.render.afp.modca.triplets.ObjectAreaSizeTriplet; import org.apache.fop.render.afp.modca.triplets.PresentationSpaceResetMixingTriplet; +import org.apache.fop.render.afp.modca.triplets.Triplet; import org.apache.fop.render.afp.tools.BinaryUtils; /** @@ -38,11 +38,11 @@ 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 widthRes The page width resolution. - * @param heightRes The page height resolution. + * + * @param width the object width. + * @param height the object height. + * @param widthRes the object width resolution. + * @param heightRes the object height resolution. */ public ObjectAreaDescriptor(int width, int height, int widthRes, int heightRes) { super(width, height, widthRes, heightRes); @@ -51,20 +51,24 @@ public class ObjectAreaDescriptor extends AbstractDescriptor { /** {@inheritDoc} */ protected byte[] getTripletData() throws IOException { if (tripletData == null) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // Specifies the associated ObjectAreaPosition structured field final byte oapId = 0x01; - new DescriptorPositionTriplet(oapId).write(bos); + Triplet triplet = new Triplet(Triplet.DESCRIPTOR_POSITION, oapId); + triplet.writeToStream(baos); + + triplet = new MeasurementUnitsTriplet(widthRes, heightRes); + triplet.writeToStream(baos); + + triplet = new ObjectAreaSizeTriplet(width, height); + triplet.writeToStream(baos); - new MeasurementUnitsTriplet(widthRes, heightRes).write(bos); + triplet = new PresentationSpaceResetMixingTriplet( + PresentationSpaceResetMixingTriplet.NOT_RESET); + triplet.writeToStream(baos); - new ObjectAreaSizeTriplet(width, height).write(bos); - - new PresentationSpaceResetMixingTriplet( - PresentationSpaceResetMixingTriplet.NOT_RESET).write(bos); - - this.tripletData = bos.toByteArray(); + this.tripletData = baos.toByteArray(); } return this.tripletData; } diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java b/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java index d853be72a..fbe8c7089 100644 --- a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java +++ b/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java @@ -30,15 +30,15 @@ import org.apache.fop.render.afp.tools.BinaryUtils; */ public class ObjectAreaPosition extends AbstractAFPObject { - private int x; - private int y; - private int rotation; + private final int x; + private final int y; + private final int rotation; private int xOffset; private int yOffset; - + /** * 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). @@ -50,14 +50,14 @@ public class ObjectAreaPosition extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[33]; copySF(data, Type.POSITION, Category.OBJECT_AREA); byte[] len = BinaryUtils.convert(32, 2); data[1] = len[0]; // Length data[2] = len[1]; - + data[9] = 0x01; // OAPosID = 1 data[10] = 0x17; // RGLength = 23 @@ -70,10 +70,10 @@ public class ObjectAreaPosition extends AbstractAFPObject { data[14] = ycoord[0]; // YoaOSet data[15] = ycoord[1]; data[16] = ycoord[2]; - + byte xorient = (byte)(rotation / 2); data[17] = xorient; // XoaOrent - + byte yorient = (byte)(rotation / 2 + 45); data[19] = yorient; // YoaOrent @@ -89,12 +89,23 @@ public class ObjectAreaPosition extends AbstractAFPObject { data[28] = 0x00; // XocaOrent data[29] = 0x00; - + data[30] = 0x2D; // YocaOrent data[31] = 0x00; data[32] = 0x01; // RefCSys - + os.write(data); } + + /** {@inheritDoc} */ + public String toString() { + return "ObjectAreaPosition{" + + "x=" + x + + ", y=" + y + + ", rotation=" + rotation + + ", rotation=" + rotation + + ", xOffset=" + xOffset + + ", yOffset=" + yOffset; + } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectContainer.java b/src/java/org/apache/fop/render/afp/modca/ObjectContainer.java index 0ad12fb92..dedeb3b8f 100644 --- a/src/java/org/apache/fop/render/afp/modca/ObjectContainer.java +++ b/src/java/org/apache/fop/render/afp/modca/ObjectContainer.java @@ -5,9 +5,9 @@ * 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. @@ -19,131 +19,85 @@ 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.AFPDataObjectInfo; import org.apache.fop.render.afp.tools.BinaryUtils; /** * Object containers are MO:DCA objects that envelop and carry object data. */ -public class ObjectContainer extends AbstractNamedAFPObject /*implements DataObjectAccessor*/ { - - private static final String DEFAULT_NAME = "OC000001"; +public class ObjectContainer extends AbstractDataObject { - /** the data object */ - private AbstractDataObject dataObj = null; - - /** the object data */ - private byte[] objectData = null; + /** the object container data maximum length */ + private static final int MAX_DATA_LEN = 32759; - /** - * Default constructor - */ - public ObjectContainer() { - super(DEFAULT_NAME); - } + /** the object data */ + protected byte[] objectData; /** * Main constructor - * + * + * @param factory the object factory * @param name the name of this object container */ - public ObjectContainer(String name) { - super(name); - } - - /** - * Sets the data object for this object container - * - * @param dataObj the data object to reside within this object container - */ - public void setDataObject(AbstractDataObject dataObj) { - this.dataObj = dataObj; + public ObjectContainer(Factory factory, String name) { + super(factory, name); } /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { - // create object data from data object - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - dataObj.write(bos); - this.objectData = bos.toByteArray(); - - byte[] data = new byte[17]; - copySF(data, Type.BEGIN, Category.OBJECT_CONTAINER); + byte[] headerData = new byte[17]; + copySF(headerData, Type.BEGIN, Category.OBJECT_CONTAINER); // Set the total record length byte[] len = BinaryUtils.convert(16 + getTripletDataLength(), 2); - data[1] = len[0]; // Length byte 1 - data[2] = len[1]; // Length byte 2 - - os.write(data); + headerData[1] = len[0]; // Length byte 1 + headerData[2] = len[1]; // Length byte 2 + + os.write(headerData); } - + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { - super.writeContent(os); - - // write out object data in chunks of object container data - for (int i = 0; i <= objectData.length; i += ObjectContainerData.MAX_DATA_LEN) { - new ObjectContainerData(objectData, i).write(os); - } + super.writeContent(os); // write OEG + + // write OCD + byte[] dataHeader = new byte[9]; + copySF(dataHeader, SF_CLASS, Type.DATA, Category.OBJECT_CONTAINER); + final int lengthOffset = 1; + writeChunksToStream(objectData, dataHeader, lengthOffset, + MAX_DATA_LEN, os); } - + /** {@inheritDoc} */ protected void writeEnd(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.END, Category.OBJECT_CONTAINER); os.write(data); } - + + /** {@inheritDoc} */ + public void setViewport(AFPDataObjectInfo dataObjectInfo) { + super.setViewport(dataObjectInfo); +// AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); +// +// int width = objectAreaInfo.getWidth(); +// int height = objectAreaInfo.getHeight(); +// int widthRes = objectAreaInfo.getWidthRes(); +// int heightRes = objectAreaInfo.getHeightRes(); +// ContainerDataDescriptor containerDataDescriptor +// = factory.createContainerDataDescriptor(width, height, widthRes, heightRes); +// getObjectEnvironmentGroup().setDataDescriptor(containerDataDescriptor); + } + /** - * An Object Container Data holds a chunk of the data object + * Sets the object container data + * + * @param data the object container data */ - private class ObjectContainerData extends AbstractPreparedAFPObject { - - /** The maximum object container data length */ - private static final int MAX_DATA_LEN = 32759; - - private byte[] objData = null; - - private int startIndex; - - /** - * Main constructor - * - * @param objData the object data - */ - public ObjectContainerData(byte[] objData, int startIndex) { - this.objData = objData; - this.startIndex = startIndex; - } - - /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { - int dataLen = MAX_DATA_LEN; - if (startIndex + MAX_DATA_LEN >= objData.length) { - dataLen = objData.length - startIndex - 1; - } - byte[] data = new byte[9 + dataLen]; - copySF(data, Type.DATA, Category.OBJECT_CONTAINER); - - byte[] len = BinaryUtils.convert(8 + dataLen, 2); - data[1] = len[0]; // Length byte 1 - data[2] = len[1]; // Length byte 2 - - // copy object data chunk - System.arraycopy(objData, startIndex, data, 9, dataLen); - os.write(data); - } - - /** {@inheritDoc} */ - public String toString() { - return "ObjectContainerData(" - + (data != null ? "" + (data.length - 2) : "null") - + ")"; - } - + public void setData(byte[] data) { + this.objectData = data; } } diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java index b2ef4fa20..9c3c5cf27 100644 --- a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java @@ -22,8 +22,7 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.ObjectAreaInfo; - +import org.apache.fop.render.afp.AFPObjectAreaInfo; /** * An Object Environment Group (OEG) may be associated with an object and is contained @@ -38,116 +37,78 @@ import org.apache.fop.render.afp.ObjectAreaInfo; */ public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject { - /** - * Default name for the object environment group - */ - private static final String DEFAULT_NAME = "OEG00001"; + private final Factory factory; - /** - * The ObjectAreaDescriptor for the object environment group - */ + /** the ObjectAreaDescriptor for the object environment group */ private ObjectAreaDescriptor objectAreaDescriptor = null; - /** - * The ObjectAreaPosition for the object environment group - */ + /** the ObjectAreaPosition for the object environment group */ private ObjectAreaPosition objectAreaPosition = null; - /** - * The ImageDataDescriptor for the object environment group - */ - private ImageDataDescriptor imageDataDescriptor = null; - - /** - * The GraphicsDataDescriptor for the object environment group - */ - private GraphicsDataDescriptor graphicsDataDescriptor = null; - - /** - * Default constructor for the ObjectEnvironmentGroup. - */ - public ObjectEnvironmentGroup() { - this(DEFAULT_NAME); - } + /** the DataDescritpor for the object environment group */ + private AbstractDescriptor dataDescriptor; /** * Constructor for the ObjectEnvironmentGroup, this takes a * name parameter which must be 8 characters long. - * + * + * @param factory the object factory * @param name the object environment group name */ - public ObjectEnvironmentGroup(String name) { + public ObjectEnvironmentGroup(Factory factory, String name) { super(name); + this.factory = factory; } /** * Sets the object area parameters. - * + * * @param info the object area info */ - public void setObjectArea(ObjectAreaInfo info) { - this.objectAreaDescriptor = new ObjectAreaDescriptor( - info.getWidth(), info.getHeight(), - info.getWidthRes(), info.getHeightRes()); - this.objectAreaPosition = new ObjectAreaPosition( + public void setObjectArea(AFPObjectAreaInfo info) { + this.objectAreaDescriptor = factory.createObjectAreaDescriptor( + info.getWidth(), info.getHeight(), info.getWidthRes(), info.getHeightRes()); + this.objectAreaPosition = factory.createObjectAreaPosition( info.getX(), info.getY(), info.getRotation()); } - /** - * 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) { - this.imageDataDescriptor = new ImageDataDescriptor(xresol, yresol, width, height); - } - - /** - * Set the graphics data descriptor. - * - * @param xresol the x resolution of the graphics window - * @param yresol the y resolution of the graphics window - * @param xlwind the left edge of the graphics window - * @param xrwind the right edge of the graphics window - * @param ybwind the top edge of the graphics window - * @param ytwind the bottom edge of the graphics window - */ - public void setGraphicsData(int xresol, int yresol, - int xlwind, int xrwind, int ybwind, int ytwind) { - this.graphicsDataDescriptor = new GraphicsDataDescriptor(xresol, yresol, - xlwind, xrwind, ybwind, ytwind); - } - /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.BEGIN, Category.OBJECT_ENVIRONMENT_GROUP); os.write(data); } - + /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); - - objectAreaDescriptor.write(os); - objectAreaPosition.write(os); - if (imageDataDescriptor != null) { - imageDataDescriptor.write(os); + if (objectAreaDescriptor != null) { + objectAreaDescriptor.writeToStream(os); + } + + if (objectAreaPosition != null) { + objectAreaPosition.writeToStream(os); } - if (graphicsDataDescriptor != null) { - graphicsDataDescriptor.write(os); + if (dataDescriptor != null) { + dataDescriptor.writeToStream(os); } } - + /** {@inheritDoc} */ protected void writeEnd(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.END, Category.OBJECT_ENVIRONMENT_GROUP); os.write(data); } + + /** + * Sets the data descriptor + * + * @param dataDescriptor the data descriptor + */ + public void setDataDescriptor(AbstractDescriptor dataDescriptor) { + this.dataDescriptor = dataDescriptor; + } } diff --git a/src/java/org/apache/fop/render/afp/modca/Overlay.java b/src/java/org/apache/fop/render/afp/modca/Overlay.java index 01b2533c2..ee2465238 100644 --- a/src/java/org/apache/fop/render/afp/modca/Overlay.java +++ b/src/java/org/apache/fop/render/afp/modca/Overlay.java @@ -22,7 +22,6 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.modca.resource.ResourceManager; /** * An overlay is a MO:DCA-P resource object. @@ -31,14 +30,14 @@ import org.apache.fop.render.afp.modca.resource.ResourceManager; * 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 { +public class Overlay extends PageObject { /** * Construct a new overlay object for the specified name argument, the overlay * name should be an 8 character identifier. - * - * @param resourceManager the resource manager * + * @param factory + * the resource manager of the page. * @param name * the name of the page. * @param width @@ -52,10 +51,10 @@ public class Overlay extends AbstractPageObject { * @param heightResolution * the height resolution of the page. */ - public Overlay(ResourceManager resourceManager, + public Overlay(Factory factory, String name, int width, int height, int rotation, int widthResolution, int heightResolution) { - super(resourceManager, name, width, height, rotation, widthResolution, heightResolution); + super(factory, name, width, height, rotation, widthResolution, heightResolution); } /** {@inheritDoc} */ diff --git a/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java b/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java index afaabfaba..7dc8c15db 100644 --- a/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/PageDescriptor.java @@ -33,7 +33,7 @@ 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 @@ -44,23 +44,15 @@ public class PageDescriptor extends AbstractDescriptor { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { - - log.debug("width=" + width); - log.debug("height=" + height); + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[24]; - data[0] = 0x5A; - data[1] = 0x00; + copySF(data, Type.DESCRIPTOR, Category.PAGE); 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 + // XpgBase data[9] = 0x00; // XpgBase = 10 inches + + // YpgBase data[10] = 0x00; // YpgBase = 10 inches // XpgUnits diff --git a/src/java/org/apache/fop/render/afp/modca/PageGroup.java b/src/java/org/apache/fop/render/afp/modca/PageGroup.java index 5fb42d197..18023756e 100644 --- a/src/java/org/apache/fop/render/afp/modca/PageGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/PageGroup.java @@ -21,10 +21,9 @@ 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.fop.render.afp.modca.resource.ResourceManager; - /** * 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 @@ -39,17 +38,17 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { /** The tag logical elements contained within this group */ private List tagLogicalElements = null; - /** The page state */ - private boolean complete = false; + /** the page group started state */ + private boolean started = false; /** * Constructor for the PageGroup. - * - * @param manager the resource manager + * + * @param factory the resource manager * @param name the name of the page group */ - public PageGroup(ResourceManager manager, String name) { - super(manager, name); + public PageGroup(Factory factory, String name) { + super(factory, name); } private List getTagLogicalElements() { @@ -58,7 +57,7 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { } return this.tagLogicalElements; } - + /** * Creates a TagLogicalElement on the page. * @@ -68,7 +67,7 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { * the value of the tag */ public void createTagLogicalElement(String name, String value) { - TagLogicalElement tle = new TagLogicalElement(name, value); + TagLogicalElement tle = factory.createTagLogicalElement(name, value); if (!getTagLogicalElements().contains(tle)) { getTagLogicalElements().add(tle); } @@ -81,14 +80,6 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { 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; - } - /** {@inheritDoc} */ protected void writeContent(OutputStream os) throws IOException { writeObjects(tagLogicalElements, os); @@ -108,7 +99,30 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { copySF(data, Type.END, Category.PAGE_GROUP); os.write(data); } - + + /** {@inheritDoc} */ + public void writeToStream(OutputStream os) throws IOException { + if (!started) { + writeStart(os); + started = true; + } + + Iterator it = objects.iterator(); + while (it.hasNext()) { + AbstractAFPObject ao = (AbstractAFPObject)it.next(); + if (ao instanceof PageObject && ((PageObject)ao).isComplete()) { + ao.writeToStream(os); + it.remove(); + } else { + break; + } + } + + if (complete) { + writeEnd(os); + } + } + /** {@inheritDoc} */ public String toString() { return this.getName(); diff --git a/src/java/org/apache/fop/render/afp/modca/PageObject.java b/src/java/org/apache/fop/render/afp/modca/PageObject.java index 01ee3e7e3..4ff75228b 100644 --- a/src/java/org/apache/fop/render/afp/modca/PageObject.java +++ b/src/java/org/apache/fop/render/afp/modca/PageObject.java @@ -22,8 +22,11 @@ package org.apache.fop.render.afp.modca; import java.io.IOException; import java.io.OutputStream; -import org.apache.fop.render.afp.modca.resource.ResourceManager; -import org.apache.fop.render.afp.tools.StringUtils; +import org.apache.fop.render.afp.ioca.ImageCellPosition; +import org.apache.fop.render.afp.ioca.ImageInputDescriptor; +import org.apache.fop.render.afp.ioca.ImageOutputControl; +import org.apache.fop.render.afp.ioca.ImageRasterData; +import org.apache.fop.render.afp.ioca.ImageRasterPattern; /** * Pages contain the data objects that comprise a presentation document. Each @@ -50,8 +53,8 @@ public class PageObject extends AbstractResourceGroupContainer { /** * Construct a new page object for the specified name argument, the page * name should be an 8 character identifier. - * - * @param resourceManager the resource manager + * + * @param factory the resource manager * * @param name * the name of the page. @@ -61,15 +64,15 @@ public class PageObject extends AbstractResourceGroupContainer { * the height of the page. * @param rotation * the rotation of the page. - * @param widthResolution + * @param widthRes * the width resolution of the page. - * @param heightResolution + * @param heightRes * the height resolution of the page. */ - public PageObject(ResourceManager resourceManager, + public PageObject(Factory factory, String name, int width, int height, int rotation, - int widthResolution, int heightResolution) { - super(resourceManager, name, width, height, rotation, widthResolution, heightResolution); + int widthRes, int heightRes) { + super(factory, name, width, height, rotation, widthRes, heightRes); } /** @@ -147,11 +150,8 @@ public class PageObject extends AbstractResourceGroupContainer { int grayscale = Math.round((shade / 255) * 16); - String imageName = "IMG" - + StringUtils.lpad(String.valueOf(getResourceCount() + 1), - '0', 5); + IMImageObject imImageObject = factory.createIMImageObject(); - IMImageObject imImageObject = new IMImageObject(imageName); ImageOutputControl imageOutputControl = new ImageOutputControl(0, 0); ImageInputDescriptor imageInputDescriptor = new ImageInputDescriptor(); ImageCellPosition imageCellPosition = new ImageCellPosition(xCoord, yCoord); @@ -161,8 +161,8 @@ public class PageObject extends AbstractResourceGroupContainer { imageCellPosition.setYSize(8); //defining this as a resource - ImageRasterData imageRasterData = new ImageRasterData( - ImageRasterPattern.getRasterData(grayscale)); + byte[] rasterData = ImageRasterPattern.getRasterData(grayscale); + ImageRasterData imageRasterData = factory.createImageRasterData(rasterData); imImageObject.setImageOutputControl(imageOutputControl); imImageObject.setImageInputDescriptor(imageInputDescriptor); @@ -184,7 +184,17 @@ public class PageObject extends AbstractResourceGroupContainer { copySF(data, Type.END, Category.PAGE); os.write(data); } - + + /** + * Adds an AFP object reference to this page + * + * @param obj an AFP object + */ + public void addObject(Object obj) { + endPresentationObject(); + super.addObject(obj); + } + /** {@inheritDoc} */ public String toString() { return this.getName(); diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java index 1d3643a61..10501f396 100644 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java +++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextData.java @@ -20,10 +20,10 @@ 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.commons.io.output.ByteArrayOutputStream; import org.apache.fop.render.afp.LineDataInfo; import org.apache.fop.render.afp.TextDataInfo; import org.apache.fop.render.afp.tools.BinaryUtils; @@ -35,18 +35,18 @@ import org.apache.fop.render.afp.tools.BinaryUtils; * 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 { @@ -58,17 +58,17 @@ public class PresentationTextData extends AbstractAFPObject { /** * The afp data relating to this presentation text data. */ - private ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); /** * The current x coordinate. */ - private int currentXCoordinate = -1; + private int currentX = -1; /** * The current y cooridnate */ - private int currentYCoordinate = -1; + private int currentY = -1; /** * The current font @@ -106,7 +106,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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. */ @@ -133,7 +133,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -154,7 +154,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -164,14 +164,14 @@ public class PresentationTextData extends AbstractAFPObject { ByteArrayOutputStream afpdata) { byte[] b = BinaryUtils.convert(coordinate, 2); afpdata.write(new byte[] {0x04, (byte) 0xC7, b[0], b[1]}, 0, 4); - currentXCoordinate = coordinate; + currentX = 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 @@ -181,15 +181,15 @@ public class PresentationTextData extends AbstractAFPObject { ByteArrayOutputStream afpdata) { byte[] b = BinaryUtils.convert(coordinate, 2); afpdata.write(new byte[] {0x04, (byte) 0xD3, b[0], b[1]}, 0, 4); - currentYCoordinate = coordinate; + currentY = coordinate; } private static final int TRANSPARENT_MAX_SIZE = 253; - + /** * 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 @@ -212,7 +212,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -240,7 +240,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -266,7 +266,7 @@ public class PresentationTextData extends AbstractAFPObject { /** * Create the presentation text data for the byte array of data. - * + * * @param textDataInfo * the afp text data * @throws MaximumSizeExceededException @@ -280,18 +280,18 @@ public class PresentationTextData extends AbstractAFPObject { if (currentOrientation != textDataInfo.getOrientation()) { setTextOrientation(textDataInfo.getOrientation(), afpdata); currentOrientation = textDataInfo.getOrientation(); - currentXCoordinate = -1; - currentYCoordinate = -1; + currentX = -1; + currentY = -1; } // Avoid unnecessary specification of the Y co-ordinate - if (textDataInfo.getY() != currentYCoordinate) { + if (textDataInfo.getY() != currentY) { absoluteMoveBaseline(textDataInfo.getY(), afpdata); - currentXCoordinate = -1; + currentX = -1; } // Avoid unnecessary specification of the X co-ordinate - if (textDataInfo.getX() != currentXCoordinate) { + if (textDataInfo.getX() != currentX) { absoluteMoveInline(textDataInfo.getX(), afpdata); } @@ -320,11 +320,11 @@ public class PresentationTextData extends AbstractAFPObject { setCodedFont(BinaryUtils.convert(textDataInfo.getFontReference())[0], afpdata); - + // Add transparent data byte[] data = textDataInfo.getData(); if (data.length <= TRANSPARENT_MAX_SIZE) { - addTransparentData(data, afpdata); + addTransparentData(data, afpdata); } else { // data size greater than TRANSPARENT_MAX_SIZE so slice int numTransData = data.length / TRANSPARENT_MAX_SIZE; @@ -337,16 +337,16 @@ public class PresentationTextData extends AbstractAFPObject { } int remainingTransData = data.length / TRANSPARENT_MAX_SIZE; buff = new byte[remainingTransData]; - System.arraycopy(data, currIndex, buff, 0, remainingTransData); + System.arraycopy(data, currIndex, buff, 0, remainingTransData); addTransparentData(buff, afpdata); } - currentXCoordinate = -1; + currentX = -1; int dataSize = afpdata.size(); if (baos.size() + dataSize > MAX_SIZE) { - currentXCoordinate = -1; - currentYCoordinate = -1; + currentX = -1; + currentY = -1; throw new MaximumSizeExceededException(); } @@ -357,7 +357,7 @@ public class PresentationTextData extends AbstractAFPObject { /** * Drawing of lines using the starting and ending coordinates, thickness and * colour arguments. - * + * * @param lineDataInfo the line data information. * @throws MaximumSizeExceededException * thrown if the maximum number of line data has been exceeded @@ -373,19 +373,19 @@ public class PresentationTextData extends AbstractAFPObject { int x2 = lineDataInfo.getX2(); int y2 = lineDataInfo.getY2(); Color col = lineDataInfo.getColor(); - + if (currentOrientation != orientation) { setTextOrientation(orientation, afpdata); currentOrientation = orientation; } // Avoid unnecessary specification of the Y coordinate - if (y1 != currentYCoordinate) { + if (y1 != currentY) { absoluteMoveBaseline(y1, afpdata); } // Avoid unnecessary specification of the X coordinate - if (x1 != currentXCoordinate) { + if (x1 != currentX) { absoluteMoveInline(x1, afpdata); } @@ -405,8 +405,8 @@ public class PresentationTextData extends AbstractAFPObject { int dataSize = afpdata.size(); if (baos.size() + dataSize > MAX_SIZE) { - currentXCoordinate = -1; - currentYCoordinate = -1; + currentX = -1; + currentY = -1; throw new MaximumSizeExceededException(); } @@ -417,12 +417,12 @@ public class PresentationTextData extends AbstractAFPObject { /** * 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 @@ -464,7 +464,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 @@ -488,13 +488,13 @@ public class PresentationTextData extends AbstractAFPObject { (byte) (col.getGreen()), // Green intensity (byte) (col.getBlue()), // Blue intensity }; - + afpdata.write(colorData, 0, colorData.length); } /** * //TODO This is a modal control sequence. - * + * * @param incr * The increment to be set. * @param afpdata @@ -513,7 +513,7 @@ public class PresentationTextData extends AbstractAFPObject { /** * //TODO This is a modal control sequence. - * + * * @param incr * The increment to be set. * @param afpdata @@ -529,7 +529,7 @@ public class PresentationTextData extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = baos.toByteArray(); byte[] size = BinaryUtils.convert(data.length - 1, 2); data[1] = size[0]; @@ -543,7 +543,7 @@ public class PresentationTextData extends AbstractAFPObject { * 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 * thrown in the event that maximum size has been exceeded */ diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java index ed72c16e6..685e79891 100644 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java +++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextDescriptor.java @@ -62,7 +62,7 @@ public class PresentationTextDescriptor extends AbstractDescriptor { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[23]; copySF(data, Type.MIGRATION, Category.PRESENTATION_TEXT); diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java index 5828b7171..25a52aefe 100644 --- a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java +++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java @@ -19,7 +19,6 @@ package org.apache.fop.render.afp.modca; -import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -41,16 +40,10 @@ import org.apache.fop.render.afp.TextDataInfo; * 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"; - - /** * The current presentation text data */ private PresentationTextData currentPresentationTextData = null; @@ -61,15 +54,9 @@ public class PresentationTextObject extends AbstractNamedAFPObject { private List/*<PresentationTextData>*/ presentationTextDataList = null; /** - * 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) { @@ -134,27 +121,6 @@ public class PresentationTextObject extends AbstractNamedAFPObject { this.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 write(OutputStream os) throws IOException { - writeStart(os); - writeObjects(this.presentationTextDataList, os); - writeEnd(os); - } - - /** - * Returns the name of this presentation text object - * - * @return the name of this presentation text object - */ - public String getName() { - return name; - } - /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; @@ -163,6 +129,11 @@ public class PresentationTextObject extends AbstractNamedAFPObject { } /** {@inheritDoc} */ + protected void writeContent(OutputStream os) throws IOException { + writeObjects(this.presentationTextDataList, os); + } + + /** {@inheritDoc} */ protected void writeEnd(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.END, Category.PRESENTATION_TEXT); @@ -187,7 +158,7 @@ public class PresentationTextObject extends AbstractNamedAFPObject { endControlSequence(); } } - + /** {@inheritDoc} */ public String toString() { if (presentationTextDataList != null) { diff --git a/src/java/org/apache/fop/render/afp/modca/Registry.java b/src/java/org/apache/fop/render/afp/modca/Registry.java index ca462c706..c81549462 100644 --- a/src/java/org/apache/fop/render/afp/modca/Registry.java +++ b/src/java/org/apache/fop/render/afp/modca/Registry.java @@ -5,9 +5,9 @@ * 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. @@ -21,33 +21,32 @@ package org.apache.fop.render.afp.modca; import java.util.Collections; -import org.apache.fop.render.afp.DataObjectInfo; import org.apache.xmlgraphics.util.MimeConstants; /** - * MOD:CA Registry of object types + * MOD:CA Registry of object types */ public final class Registry { - /** IOB supported object types */ - private static final byte COMPID_GIF = 22; - private static final byte COMPID_JFIF = 23; // jpeg file interchange format - private static final byte COMPID_PDF_SINGLE_PAGE = 25; - private static final byte COMPID_PCL_PAGE_OBJECT = 34; - - /** IOB unsupported object types */ + /** IOB supported object types */ private static final byte COMPID_EPS = 13; private static final byte COMPID_TIFF = 14; + private static final byte COMPID_GIF = 22; + private static final byte COMPID_JFIF = 23; // jpeg file interchange format + private static final byte COMPID_PDF_SINGLE_PAGE = 25; + private static final byte COMPID_PCL_PAGE_OBJECT = 34; /** mime type entry mapping */ - private java.util.Map/*<String, Registry.ObjectType>*/ mimeObjectTypeMap + private final java.util.Map/*<String, ObjectType>*/ mimeObjectTypeMap = Collections.synchronizedMap( - new java.util.HashMap/*<String, Registry.ObjectType>*/()); + new java.util.HashMap/*<String, ObjectType>*/()); /** singleton instance */ private static Registry instance = null; /** - * @return a single instance of an ObjectTypeRegistry + * Returns a single instance of a MO:DCA Registry + * + * @return a single instance of an MO:DCA Registry */ public static Registry getInstance() { synchronized (Registry.class) { @@ -57,11 +56,17 @@ public final class Registry { } return instance; } - + + /** + * private constructor + */ private Registry() { init(); } - + + /** + * Initializes the mimetype map + */ private void init() { mimeObjectTypeMap.put( MimeConstants.MIME_EPS, @@ -69,7 +74,7 @@ public final class Registry { COMPID_EPS, new byte[] {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0D}, "Encapsulated Postscript", - false, + true, MimeConstants.MIME_EPS ) ); @@ -79,7 +84,7 @@ public final class Registry { COMPID_TIFF, new byte[] {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0E}, "TIFF", - false, + true, MimeConstants.MIME_TIFF ) ); @@ -111,7 +116,7 @@ public final class Registry { true, MimeConstants.MIME_PDF ) - ); + ); mimeObjectTypeMap.put( MimeConstants.MIME_PCL, new ObjectType( @@ -121,38 +126,32 @@ public final class Registry { true, MimeConstants.MIME_PCL ) - ); + ); } /** - * Returns the Registry ObjectType for a given data object info - * or null if not registered - * - * @param dataObjectInfo the data object info - * @return the Registry ObjectType for a given data object info - * or null if not registered + * Returns the MOD:CA object type given a mimetype + * + * @param mimeType the object mimetype + * @return the MOD:CA object type */ - public Registry.ObjectType getObjectType(DataObjectInfo dataObjectInfo) { - String mimeType = dataObjectInfo.getMimeType(); - if (mimeType != null) { - return (Registry.ObjectType)mimeObjectTypeMap.get(mimeType); - } - return null; + public ObjectType getObjectType(String mimeType) { + return (ObjectType)mimeObjectTypeMap.get(mimeType); } /** * Encapsulates a MOD:CA Registry Object Type entry */ public class ObjectType { - private byte componentId; - private byte[] oid; - private String name; - private boolean includable; - private String mimeType; + private final byte componentId; + private final byte[] oid; + private final String name; + private final boolean includable; + private final String mimeType; /** * Main constructor - * + * * @param componentId the component id of this object type * @param oid the object id of this object type * @param name the object type name @@ -167,10 +166,10 @@ public final class Registry { this.componentId = componentId; this.oid = oid; } - + /** * Returns a MOD:CA object type OID from a given a componentId - * + * * @return the corresponding object type id for a given component id * or null if the component id is unknown and the object type OID was not found. */ @@ -180,8 +179,8 @@ public final class Registry { /** * Returns the object type name for the given componentId - * - * @return the object type name for the given componentId + * + * @return the object type name for the given componentId */ public String getName() { return this.name; @@ -189,7 +188,7 @@ public final class Registry { /** * Returns the compontentId for this entry - * + * * @return the compontentId for this entry */ public byte getComponentId() { @@ -198,7 +197,7 @@ public final class Registry { /** * Returns true if this component can be included with an IOB structured field - * + * * @return true if this component can be included with an IOB structured field */ public boolean isIncludable() { @@ -207,7 +206,7 @@ public final class Registry { /** * Returns the mime type associated with this object type - * + * * @return the mime type associated with this object type */ public String getMimeType() { diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java index 1282d13aa..9e89144f4 100644 --- a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java +++ b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java @@ -24,163 +24,82 @@ import java.io.OutputStream; import java.util.Iterator; import java.util.Set; -import org.apache.fop.render.afp.modca.resource.ResourceManager; -import org.apache.fop.render.afp.modca.resource.ResourceStore; -import org.apache.fop.render.afp.modca.resource.StoreInfo; +import org.apache.fop.util.store.Streamable; /** * 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"; +public class ResourceGroup extends AbstractNamedAFPObject { /** Set of resource uri */ - private Set/*<String>*/ resourceSet = new java.util.HashSet/*<String>*/(); - - private ResourceManager resourceManager; - - /** - * Default constructor - */ - public ResourceGroup(ResourceManager resourceManager) { - this(resourceManager, DEFAULT_NAME); - } + private final Set/*<String>*/ resourceSet = new java.util.HashSet/*<String>*/(); /** * Constructor for the ResourceGroup, this takes a * name parameter which must be 8 characters long. - * + * * @param name the resource group name - * @param resourceManager the resource group manager */ - public ResourceGroup(ResourceManager resourceManager, String name) { + public ResourceGroup(String name) { super(name); - this.resourceManager = resourceManager; } - -// /** -// * Creates a data object in this resource group -// * -// * @param dataObjectInfo the data object info -// * @return an include object reference -// */ -// public IncludeObject createObject(DataObjectInfo dataObjectInfo) { -// String uri = dataObjectInfo.getUri(); -// resourceSet.get(); -// DataObjectAccessor dataObjectAccessor -// = (DataObjectAccessor)getResourceMap().getData(dataObjectInfo.getUri()); -// ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); -// ResourceLevel resourceLevel = resourceInfo.getLevel(); -// AbstractDataObject dataObj; -// if (dataObjectAccessor == null) { -// dataObj = dataObjectFactory.createObject(dataObjectInfo); -// ObjectContainer objectContainer = null; -// String resourceName = resourceInfo.getName(); -// if (resourceName != null) { -// objectContainer = new ObjectContainer(resourceName); -// } else { -// objectContainer = createObjectContainer(); -// resourceName = objectContainer.getName(); -// } -// objectContainer.setDataObject(dataObj); -// objectContainer.setDataObjectInfo(dataObjectInfo); -// -// // When located at print-file level or externally, -// // wrap the object container in a resource object -// if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) { -// ResourceObject resourceObject = new ResourceObject(resourceName); -// resourceObject.setDataObject(objectContainer); -// resourceObject.setDataObjectInfo(dataObjectInfo); -// dataObjectAccessor = resourceObject; -// } else { // Access data object through container -// dataObjectAccessor = objectContainer; -// } -// -// // Add to resource map -// getResourceMap().put(dataObjectInfo.getUri(), dataObjectAccessor); -// } -// String name = dataObjectAccessor.getName(); -// IncludeObject includeObj = dataObjectFactory.createInclude(dataObjectInfo); -// return includeObj; -// } - -// /** -// * Checks if a named object is of a valid type to be added to a resource group -// * -// * @param namedObj a named object -// * @return true if the named object is of a valid type to be added to a resource group -// */ -// private boolean isValidObjectType(AbstractNamedAFPObject namedObj) { -// return (namedObj instanceof Overlay -// || namedObj instanceof ResourceObject -// || namedObj instanceof PageSegment -// || namedObj instanceof GraphicsObject -// || namedObj instanceof ImageObject -// || namedObj instanceof ObjectContainer -// || namedObj instanceof Document -// // || namedObj instanceof FormMap -// // || namedObj instanceof BarcodeObject -// ); -// } /** - * Add this object cache record to this resource group - * - * @param record the cache record + * Add this named object to this resource group + * + * @param namedObject a named object + * @throws IOException thrown if an I/O exception of some sort has occurred. */ - public void addObject(StoreInfo record) { - resourceSet.add(record); + public void addObject(AbstractNamedAFPObject namedObject) throws IOException { + resourceSet.add(namedObject); } - + /** * Returns the number of resources contained in this resource group - * + * * @return the number of resources contained in this resource group */ public int getResourceCount() { - return resourceSet.size(); + return resourceSet.size(); } - + /** * Returns true if the resource exists within this resource group, * false otherwise. - * + * * @param uri the uri of the resource * @return true if the resource exists within this resource group */ public boolean resourceExists(String uri) { return resourceSet.contains(uri); } - - /** {@inheritDoc} */ - public void writeContent(OutputStream os) throws IOException { - Iterator it = resourceSet.iterator(); - - if (it.hasNext()) { - ResourceStore store = resourceManager.getStore(); - do { - StoreInfo saveInfo = (StoreInfo)it.next(); - store.writeToStream(saveInfo, os); - } while (it.hasNext()); - } - } /** {@inheritDoc} */ - protected void writeStart(OutputStream os) throws IOException { + public void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.BEGIN, Category.RESOURCE_GROUP); os.write(data); } /** {@inheritDoc} */ - protected void writeEnd(OutputStream os) throws IOException { + public void writeContent(OutputStream os) throws IOException { + Iterator it = resourceSet.iterator(); + while (it.hasNext()) { + Object object = it.next(); + if (object instanceof Streamable) { + Streamable streamableObject = (Streamable)object; + streamableObject.writeToStream(os); + } + } + } + + /** {@inheritDoc} */ + public void writeEnd(OutputStream os) throws IOException { byte[] data = new byte[17]; copySF(data, Type.END, Category.RESOURCE_GROUP); os.write(data); } - + /** {@inheritDoc} */ public String toString() { return this.name + " " + resourceSet/*getResourceMap()*/; diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceObject.java b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java index e3f8621e0..01a48f440 100644 --- a/src/java/org/apache/fop/render/afp/modca/ResourceObject.java +++ b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java @@ -5,9 +5,9 @@ * 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. @@ -27,15 +27,15 @@ import org.apache.fop.render.afp.tools.BinaryUtils; /** * This resource structured field begins an envelope that is used to carry - * resource objects in print-file-level (external) resource groups. + * resource objects in print-file-level (external) resource groups. */ public class ResourceObject extends AbstractPreparedAFPObject { - + private AbstractNamedAFPObject namedObject; - + /** * Default constructor - * + * * @param name the name of this resource (reference id) */ public ResourceObject(String name) { @@ -44,13 +44,13 @@ public class ResourceObject extends AbstractPreparedAFPObject { /** * Sets the data object referenced by this resource object - * + * * @param obj the named data object */ public void setDataObject(AbstractNamedAFPObject obj) { this.namedObject = obj; } - + /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { super.writeStart(os); @@ -62,10 +62,11 @@ public class ResourceObject extends AbstractPreparedAFPObject { byte[] len = BinaryUtils.convert(18 + getTripletDataLength(), 2); data[1] = len[0]; // Length byte 1 data[2] = len[1]; // Length byte 2 - + // Set reserved bits data[17] = 0x00; // Reserved data[18] = 0x00; // Reserved + os.write(data); } @@ -73,7 +74,7 @@ public class ResourceObject extends AbstractPreparedAFPObject { protected void writeContent(OutputStream os) throws IOException { super.writeContent(os); // write triplets if (namedObject != null) { - namedObject.write(os); + namedObject.writeToStream(os); } } @@ -83,15 +84,15 @@ public class ResourceObject extends AbstractPreparedAFPObject { copySF(data, Type.END, Category.NAME_RESOURCE); os.write(data); } - + /** {@inheritDoc} */ public String toString() { return this.getName(); } - + /** * Sets Resource Object Type triplet - * + * * @param type the resource object type */ public void setType(byte type) { @@ -100,17 +101,17 @@ public class ResourceObject extends AbstractPreparedAFPObject { /** graphics object type */ public static final byte TYPE_GRAPHIC = 0x03; - + /** barcode object type */ public static final byte BARCODE = 0x05; /** image object type */ public static final byte TYPE_IMAGE = 0x06; - + // private static final byte FONT_CHARACTER_SET = 0x40; // private static final byte CODE_PAGE = 0x41; // private static final byte CODED_FONT = 0x42; - + /** object container type */ public static final byte TYPE_OBJECT_CONTAINER = (byte) 0x92; @@ -122,7 +123,7 @@ public class ResourceObject extends AbstractPreparedAFPObject { /** overlay object type */ public static final byte TYPE_OVERLAY_OBJECT = (byte) 0xFC; - + // private static final byte PAGEDEF = (byte) 0xFD; // private static final byte FORMDEF = (byte) 0xFE; @@ -132,7 +133,7 @@ public class ResourceObject extends AbstractPreparedAFPObject { /** * Main constructor - * + * * @param type * the resource objec type */ diff --git a/src/java/org/apache/fop/render/afp/modca/StreamedResourceGroup.java b/src/java/org/apache/fop/render/afp/modca/StreamedResourceGroup.java new file mode 100644 index 000000000..abe2e1547 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/modca/StreamedResourceGroup.java @@ -0,0 +1,92 @@ +/* + * 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; + +/** + * A print-file resource group + */ +public class StreamedResourceGroup extends ResourceGroup { + /** the outputstream to write to */ + private final OutputStream os; + + private boolean started = false; + + private boolean complete = false; + + /** + * Main constructor + * + * @param name the resource group name + * @param os the outputstream + */ + public StreamedResourceGroup(String name, OutputStream os) { + super(name); + this.os = os; + } + + /** + * Adds a resource to the external resource group + * + * @param namedObject a named object + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + public void addObject(AbstractNamedAFPObject namedObject) throws IOException { + if (!started) { + writeStart(os); + started = true; + } + try { + namedObject.writeToStream(os); + } finally { + os.flush(); + } + } + + /** + * Closes this external resource group file + * + * @throws IOException thrown if an I/O exception of some sort has occurred. + */ + public void close() throws IOException { + writeEnd(os); + complete = true; + } + + /** + * Returns true if this resource group is complete + * + * @return true if this resource group is complete + */ + public boolean isComplete() { + return this.complete; + } + + /** + * Returns the outputstream + * + * @return the outputstream + */ + public OutputStream getOutputStream() { + return this.os; + } +}
\ 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 index 5f98090a1..64160c087 100644 --- a/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java +++ b/src/java/org/apache/fop/render/afp/modca/TagLogicalElement.java @@ -69,7 +69,7 @@ public class TagLogicalElement extends AbstractAFPObject { } /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { byte[] data = new byte[17 + name.length() + value.length()]; diff --git a/src/java/org/apache/fop/render/afp/modca/Writable.java b/src/java/org/apache/fop/render/afp/modca/Writable.java deleted file mode 100644 index aa9de2d43..000000000 --- a/src/java/org/apache/fop/render/afp/modca/Writable.java +++ /dev/null @@ -1,38 +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; - -/** - * Implementing object is able to write to an AFPDataStream - */ -public interface Writable { - - /** - * DataStream objects must implement the write() - * method to write its data to the given OutputStream - * - * @param outputStream The outputsteam stream - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - void write(OutputStream outputStream) throws IOException; -} diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java b/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java deleted file mode 100644 index 2c55d7618..000000000 --- a/src/java/org/apache/fop/render/afp/modca/resource/ExternalResourceManager.java +++ /dev/null @@ -1,143 +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: $ */ - -/* - * 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.resource; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Iterator; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.fop.render.afp.ResourceLevel; -import org.apache.fop.render.afp.modca.ResourceGroup; - -/** - * Manages resource groups (external) - */ -public class ExternalResourceManager { - - /** Static logging instance */ - static final Log log = LogFactory.getLog(ExternalResourceManager.class); - - /** the resource manager */ - private final ResourceManager resourceManager; - - /** - * Main constructor - * - * @param resourceManager the resource manager - */ - public ExternalResourceManager(ResourceManager resourceManager) { - this.resourceManager = resourceManager; - } - - /** A mapping of external resource destinations to resource groups */ - private Map/*<String,ResourceGroup>*/pathResourceGroupMap - = new java.util.HashMap/*<String,ResourceGroup>*/(); - - /** Sets the default resource group file */ - private String defaultFilePath; - - /** - * Sets the default resource group file - * - * @param filePath the default resource group file path - */ - public void setDefaultFilePath(String filePath) { - this.defaultFilePath = filePath; - } - - /** - * Returns the corresponding resource group for the given resource level - * - * @param level the resource level - * @return the corresponding resource group for the given resource level - * or null if not found. - */ - public ResourceGroup getResourceGroup(ResourceLevel level) { - ResourceGroup resourceGroup = null; - // this resource info does not have an external resource group - // file definition - String filePath = level.getExternalFilePath(); - if (filePath != null) { - filePath = level.getExternalFilePath(); - resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath); - if (resourceGroup == null) { - ResourceFactory factory = resourceManager.getFactory(); - resourceGroup = factory.createResourceGroup(); - pathResourceGroupMap.put(filePath, resourceGroup); - } - } else if (defaultFilePath != null) { - // fallback to default resource group file - level.setExternalFilePath(defaultFilePath); - resourceGroup = getResourceGroup(level); - } - return resourceGroup; - } - - /** - * Writes out all resource groups to external files - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public void write() throws IOException { - // write any external resources - Iterator it = pathResourceGroupMap.keySet().iterator(); - while (it.hasNext()) { - String filePath = (String)it.next(); - ResourceGroup resourceGroup - = (ResourceGroup)pathResourceGroupMap.get(filePath); - OutputStream os = null; - try { - log.debug("Writing external AFP resource file " + filePath); - os = new java.io.FileOutputStream(filePath); - resourceGroup.write(os); - } finally { - if (os != null) { - try { - os.close(); - } catch (IOException e) { - log.error("Failed to close outputstream for external AFP resource file " - + filePath); - } - } - } - } - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java deleted file mode 100644 index 796ffff1a..000000000 --- a/src/java/org/apache/fop/render/afp/modca/resource/ResourceFactory.java +++ /dev/null @@ -1,485 +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.resource; - -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.render.afp.DataObjectInfo; -import org.apache.fop.render.afp.GraphicsObjectInfo; -import org.apache.fop.render.afp.GraphicsObjectPainter; -import org.apache.fop.render.afp.ImageObjectInfo; -import org.apache.fop.render.afp.ObjectAreaInfo; -import org.apache.fop.render.afp.ResourceInfo; -import org.apache.fop.render.afp.ResourceLevel; -import org.apache.fop.render.afp.modca.AbstractDataObject; -import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; -import org.apache.fop.render.afp.modca.Document; -import org.apache.fop.render.afp.modca.GraphicsObject; -import org.apache.fop.render.afp.modca.ImageContent; -import org.apache.fop.render.afp.modca.ImageObject; -import org.apache.fop.render.afp.modca.IncludeObject; -import org.apache.fop.render.afp.modca.ObjectContainer; -import org.apache.fop.render.afp.modca.Overlay; -import org.apache.fop.render.afp.modca.PageGroup; -import org.apache.fop.render.afp.modca.PageObject; -import org.apache.fop.render.afp.modca.PageSegment; -import org.apache.fop.render.afp.modca.Registry; -import org.apache.fop.render.afp.modca.ResourceGroup; -import org.apache.fop.render.afp.modca.ResourceObject; -import org.apache.fop.render.afp.modca.Registry.ObjectType; -import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet; -import org.apache.fop.render.afp.modca.triplets.MappingOptionTriplet; -import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet; -import org.apache.fop.render.afp.tools.StringUtils; - -import org.apache.xmlgraphics.image.codec.tiff.TIFFImage; - -/** - * Creator of MO:DCA data objects - */ -public class ResourceFactory { - - /** Static logging instance */ - private static final Log log = LogFactory.getLog(ResourceFactory.class); - - private static final String IMAGE_NAME_PREFIX = "IMG"; - - private static final String GRAPHIC_NAME_PREFIX = "GRA"; - - private static final String BARCODE_NAME_PREFIX = "BAR"; - -// private static final String OTHER_NAME_PREFIX = "OTH"; - - private static final String OBJECT_CONTAINER_NAME_PREFIX = "OC"; - - private static final String RESOURCE_NAME_PREFIX = "RES"; - - /** Default name for the resource group */ - private static final String RESOURCE_GROUP_NAME_PREFIX = "RG"; - - private static final String PAGE_GROUP_NAME_PREFIX = "PGP"; - - private static final String PAGE_NAME_PREFIX = "PGN"; - - private static final String OVERLAY_NAME_PREFIX = "OVL"; - - - private Map/*<ResourceInfo,IncludeObject>*/ includeMap - = new java.util.HashMap/*<ResourceInfo,IncludeObject>*/(); - - private ResourceManager manager; - - - /** The page group count */ - private int pageGroupCount = 0; - - /** The page count */ - private int pageCount = 0; - - /** The image count */ - private int imageCount = 0; - - /** The graphic count */ - private int graphicCount = 0; - - /** The object container count */ - private int objectContainerCount = 0; - - /** The resource count */ - private int resourceCount = 0; - - /** The resource group count */ - private int resourceGroupCount = 0; - - /** The overlay count */ - private int overlayCount = 0; - - /** - * Main constructor - * - * @param resourceManager the resource manager - */ - public ResourceFactory(ResourceManager resourceManager) { - this.manager = resourceManager; - } - - /** - * Converts a byte array containing 24 bit RGB image data to a grayscale - * image. - * - * @param io - * the target image object - * @param info - * the image object info - * - * @return the converted image data - */ - private static byte[] convertToGrayScaleImage(ImageObject io, ImageObjectInfo info) { - byte[] raw = info.getData(); - int width = info.getDataWidth(); - int height = info.getDataHeight(); - int bitsPerPixel = info.getBitsPerPixel(); - - int pixelsPerByte = 8 / bitsPerPixel; - int bytewidth = (width / pixelsPerByte); - if ((width % pixelsPerByte) != 0) { - bytewidth++; - } - byte[] data = 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)) { - data[(y * bytewidth) + (x / pixelsPerByte)] = ib; - ib = 0; - } - } - } - return data; - } - - /** - * Helper method to create an image on the current container and to return - * the object. - * - * @param imageObjectInfo the image object info - * @return a newly created image object - */ - private ImageObject createImage(ImageObjectInfo imageObjectInfo) { - String name = IMAGE_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++imageCount), '0', 5); - ImageObject imageObj = new ImageObject(name); - if (imageObjectInfo.hasCompression()) { - int compression = imageObjectInfo.getCompression(); - switch (compression) { - case TIFFImage.COMP_FAX_G3_1D: - imageObj.setImageEncoding(ImageContent.COMPID_G3_MH); - break; - case TIFFImage.COMP_FAX_G3_2D: - imageObj.setImageEncoding(ImageContent.COMPID_G3_MR); - break; - case TIFFImage.COMP_FAX_G4_2D: - imageObj.setImageEncoding(ImageContent.COMPID_G3_MMR); - break; - default: - throw new IllegalStateException( - "Invalid compression scheme: " + compression); - } - } - ObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo(); - imageObj.setImageParameters(objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes(), - imageObjectInfo.getDataWidth(), imageObjectInfo.getDataHeight()); - if (imageObjectInfo.isBuffered()) { - if (imageObjectInfo.isColor()) { - imageObj.setImageIDESize((byte)24); - imageObj.setImageData(imageObjectInfo.getData()); - } else { - int bitsPerPixel = imageObjectInfo.getBitsPerPixel(); - imageObj.setImageIDESize((byte)bitsPerPixel); - byte[] data = convertToGrayScaleImage(imageObj, imageObjectInfo); - imageObj.setImageData(data); - } - } - return imageObj; - } - - /** - * Creates and returns a new graphics object. - * - * @param graphicsObjectInfo the graphics object info - * @return a new graphics object - */ - private GraphicsObject createGraphic(GraphicsObjectInfo graphicsObjectInfo) { - String name = GRAPHIC_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++graphicCount), '0', 5); - GraphicsObject graphicsObj = new GraphicsObject(name); - - // paint the graphic using batik - GraphicsObjectPainter painter = graphicsObjectInfo.getPainter(); - painter.paint(graphicsObj); - - return graphicsObj; - } - - /** - * Creates and returns a new object container - * - * @return a new object container - */ - private ObjectContainer createObjectContainer() { - String name = OBJECT_CONTAINER_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++objectContainerCount), '0', 6); - return new ObjectContainer(name); - } - - /** - * Creates and returns a new resource object - * - * @param resourceName the resource name - * @return a new resource object - */ - private ResourceObject createResource(String resourceName) { - return new ResourceObject(resourceName); - } - - /** - * Creates and returns a new resource object - * - * @return a new resource object - */ - private ResourceObject createResource() { - String name = RESOURCE_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++resourceCount), '0', 5); - return createResource(name); - } - - /** - * Creates and returns a new include object. - * - * @param name the name of this include object - * @param dataObjectInfo a data object info - * - * @return a new include object - */ - public IncludeObject createInclude(String name, DataObjectInfo dataObjectInfo) { - ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); - IncludeObject includeObj = (IncludeObject)includeMap.get(resourceInfo); - if (includeObj == null) { - includeObj = new IncludeObject(name); - - if (dataObjectInfo instanceof ImageObjectInfo) { - includeObj.setDataObjectType(IncludeObject.TYPE_IMAGE); - } else if (dataObjectInfo instanceof GraphicsObjectInfo) { - includeObj.setDataObjectType(IncludeObject.TYPE_GRAPHIC); - } else { - includeObj.setDataObjectType(IncludeObject.TYPE_OTHER); - } - - Registry.ObjectType objectType = dataObjectInfo.getObjectType(); - if (objectType != null) { - includeObj.setObjectClassification( - ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, - objectType); - } - - ObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo(); - - includeObj.setObjectArea(objectAreaInfo.getX(), objectAreaInfo.getY()); - - includeObj.setObjectAreaSize( - objectAreaInfo.getWidth(), objectAreaInfo.getHeight()); - - includeObj.setMeasurementUnits( - objectAreaInfo.getWidthRes(), objectAreaInfo.getHeightRes()); - - includeObj.setMappingOption(MappingOptionTriplet.SCALE_TO_FIT); - - includeMap.put(resourceInfo, includeObj); - } - - return includeObj; - } - - /** - * Creates and returns a new page group - * - * @return a new page group object - */ - public PageGroup createPageGroup() { - String name = PAGE_GROUP_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++pageGroupCount), '0', 5); - return new PageGroup(manager, name); - } - - /** - * Creates and returns a new resource object - * - * @return a new resource object - */ - public ResourceGroup createResourceGroup() { - String name = RESOURCE_GROUP_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++resourceGroupCount), '0', 6); - return new ResourceGroup(manager, name); - } - - /** - * Creates and returns a new page object - * - * @param pageWidth - * the width of the page - * @param pageHeight - * the height of the page - * @param pageRotation - * the rotation of the page - * @param pageWidthRes - * the width resolution of the page - * @param pageHeightRes - * the height resolution of the page - * - * @return a new page object - */ - public PageObject createPage(int pageWidth, int pageHeight, int pageRotation, - int pageWidthRes, int pageHeightRes) { - String pageName = PAGE_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++pageCount), '0', 5); - return new PageObject(manager, pageName, pageWidth, pageHeight, - pageRotation, pageWidthRes, pageHeightRes); - } - - - /** - * Creates and returns a new Overlay. - * - * @param width - * the width of the overlay - * @param height - * the height of the overlay - * @param widthRes - * the width resolution of the overlay - * @param heightRes - * the height resolution of the overlay - * @param overlayRotation - * the rotation of the overlay - * - * @return a new overlay object - */ - public Overlay createOverlay(int width, int height, - int widthRes, int heightRes, int overlayRotation) { - String overlayName = OVERLAY_NAME_PREFIX - + StringUtils.lpad(String.valueOf(++overlayCount), '0', 5); - Overlay overlay = new Overlay(manager, overlayName, width, height, - overlayRotation, widthRes, heightRes); - return overlay; - } - - /** - * Creates a new MO:DCA document object - * - * @return a new MO:DCA document object - */ - public Document createDocument() { - return new Document(manager); - } - - /** - * Creates and returns a new data object - * - * @param dataObjectInfo the data object info - * - * @return a newly created data object - */ - public AbstractNamedAFPObject create(DataObjectInfo dataObjectInfo) { - AbstractNamedAFPObject dataObj; - - if (dataObjectInfo instanceof ImageObjectInfo) { - dataObj = createImage((ImageObjectInfo)dataObjectInfo); - } else if (dataObjectInfo instanceof GraphicsObjectInfo) { - dataObj = createGraphic((GraphicsObjectInfo)dataObjectInfo); - } else { - throw new IllegalArgumentException("Unknown data object type: " + dataObjectInfo); - } - - if (dataObj instanceof AbstractDataObject) { - ((AbstractDataObject)dataObj).setViewport(dataObjectInfo.getObjectAreaInfo()); - } - - dataObj.setFullyQualifiedName( - FullyQualifiedNameTriplet.TYPE_DATA_OBJECT_INTERNAL_RESOURCE_REF, - FullyQualifiedNameTriplet.FORMAT_CHARSTR, dataObj.getName()); - - ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); - ResourceLevel resourceLevel = resourceInfo.getLevel(); - - if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) { - - ObjectType objectType = dataObjectInfo.getObjectType(); - - if (objectType != null && objectType.isIncludable()) { - - // Wrap newly created data object in a resource object - // if it is to reside within a resource group at print-file or external level - if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) { - ResourceObject resourceObj = null; - String resourceName = resourceInfo.getName(); - if (resourceName != null) { - resourceObj = createResource(resourceName); - } else { - resourceObj = createResource(); - } - - if (dataObj instanceof ObjectContainer) { - resourceObj.setType(ResourceObject.TYPE_OBJECT_CONTAINER); - } else if (dataObj instanceof ImageObject) { - resourceObj.setType(ResourceObject.TYPE_IMAGE); - } else if (dataObj instanceof GraphicsObject) { - resourceObj.setType(ResourceObject.TYPE_GRAPHIC); - } else if (dataObj instanceof Document) { - resourceObj.setType(ResourceObject.TYPE_DOCUMENT); - } else if (dataObj instanceof PageSegment) { - resourceObj.setType(ResourceObject.TYPE_PAGE_SEGMENT); - } else if (dataObj instanceof Overlay) { - resourceObj.setType(ResourceObject.TYPE_OVERLAY_OBJECT); - } else { - throw new UnsupportedOperationException( - "Unsupported resource object type " + dataObj); - } - - resourceObj.setObjectClassification( - ObjectClassificationTriplet.CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT, - objectType); - - resourceObj.setDataObject(dataObj); - dataObj = resourceObj; - } - } - } - - return dataObj; - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.java deleted file mode 100644 index 01368fa07..000000000 --- a/src/java/org/apache/fop/render/afp/modca/resource/ResourceManager.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.resource; - -import java.io.IOException; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.render.afp.DataObjectInfo; -import org.apache.fop.render.afp.ResourceInfo; -import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; -import org.apache.fop.render.afp.modca.Registry; - -/** - * Manages the creation and storage of document resources - */ -public class ResourceManager { - /** Static logging instance */ - static final Log log = LogFactory.getLog(ResourceManager.class); - - /** Resource storage */ - private ResourceStore store; - - /** Resource creation factory */ - private ResourceFactory factory; - - private ExternalResourceManager external; - - /** Mapping of resource info --> store info */ - private Map/*<ResourceInfo,StoreInfo>*/ resourceStorageMap - = new java.util.HashMap/*<ResourceInfo,StoreInfo>*/(); - - /** - * Main constructor - */ - public ResourceManager() { - this.factory = new ResourceFactory(this); - this.store = new ResourceStore(); - this.external = new ExternalResourceManager(this); - } - - /** - * Creates and adds a new data object and stores the save record to a temporary file. - * - * @param dataObjectInfo a data object info - * - * @return a new store save information record - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public StoreInfo create(DataObjectInfo dataObjectInfo) throws IOException { - StoreInfo storeInfo = null; - Registry.ObjectType objectType = dataObjectInfo.getObjectType(); - if (objectType == null || !objectType.isIncludable()) { - AbstractNamedAFPObject dataObj = factory.create(dataObjectInfo); - if (dataObj == null) { - log.error("Failed to create object: " + dataObjectInfo); - return null; - } - storeInfo = store.save(dataObj); - } else { - ResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); - storeInfo = (StoreInfo)resourceStorageMap.get(resourceInfo); - if (storeInfo == null) { - AbstractNamedAFPObject dataObj = factory.create(dataObjectInfo); - if (dataObj == null) { - log.error("Failed to create object: " + dataObjectInfo); - return null; - } - storeInfo = store.save(dataObj); - resourceStorageMap.put(resourceInfo, storeInfo); - } - } - return storeInfo; - } - - /** - * Returns the resource factory - * - * @return the resource factory - */ - public ResourceFactory getFactory() { - return this.factory; - } - - /** - * Returns the resource store - * - * @return the resource store - */ - public ResourceStore getStore() { - return this.store; - } - - /** - * Returns the resource group manager - * - * @return the resource group manager - */ - public ExternalResourceManager getExternalManager() { - return this.external; - } - - /** - * Writes out all external resource groups that are held - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public void writeExternal() throws IOException { - external.write(); - } - - /** - * Clears the store - * @throws IOException if an error occurs while clearing the resource store - */ - public void clearStore() throws IOException { - store.clear(); - } -} diff --git a/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java b/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java deleted file mode 100644 index edec749d5..000000000 --- a/src/java/org/apache/fop/render/afp/modca/resource/ResourceStore.java +++ /dev/null @@ -1,142 +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.resource; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.fop.render.afp.modca.AbstractNamedAFPObject; - -/** - * Caches and creates (as necessary using an instance of DataObjectFactory) - * descendants of AbstractDataObject - */ -public final class ResourceStore { - - /** Static logging instance */ - private static final Log log = LogFactory.getLog(ResourceStore.class); - - private static final String TEMPFILE_PREFIX = "AFP_"; - - /** Internal temporary storage buffer size */ - private static final int BUFFER_SIZE = 4096; - - /** Used for storage of data objects */ - private RandomAccessFile raFile; - - /** The temporary cache file */ - private File tempFile; - - /** The file outputstream */ - private FileOutputStream fos; - - /** - * Default constructor - */ - public ResourceStore() { - try { - this.tempFile = File.createTempFile(TEMPFILE_PREFIX, null); - this.raFile = new RandomAccessFile(tempFile, "rw"); - FileDescriptor fd = raFile.getFD(); - this.fos = new FileOutputStream(fd); - } catch (IOException e) { - // TODO - log.error(e.getMessage()); - } - } - - /** - * Clears the data object cache. - * @throws IOException if an error occurs while clearing the store - */ - public void clear() throws IOException { - if (tempFile != null) { - raFile.close(); - raFile = null; - fos = null; - if (tempFile.exists() && !tempFile.delete()) { - throw new IOException("Could not delete temporary file: " + tempFile); - } - tempFile = null; - } - } - - /** {@inheritDoc} */ - public void finalize() throws Throwable { - try { - clear(); - } finally { - super.finalize(); - } - } - - /** - * Stores a named data object in the cache - * - * @param dataObj a named data object - * @return a new save information record - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public StoreInfo save(AbstractNamedAFPObject dataObj) throws IOException { - StoreInfo storeInfo = new StoreInfo(); - storeInfo.objectName = dataObj.getName(); - storeInfo.position = raFile.getFilePointer(); - try { - dataObj.write(fos); - } finally { - fos.flush(); - } - storeInfo.size = (int)(raFile.getFilePointer() - storeInfo.position); - return storeInfo; - } - - /** - * Writes out the resource given the save information to the given outputstream. - * - * @param saveInfo the save information - * @param os the outputstream to write to - * - * @throws java.io.IOException an I/O exception of some sort has occurred. - */ - public void writeToStream(StoreInfo saveInfo, OutputStream os) throws IOException { - if (saveInfo == null) { - throw new IllegalArgumentException("save is null"); - } - double chunkCount = saveInfo.size / BUFFER_SIZE; - byte[] buffer = new byte[BUFFER_SIZE]; - raFile.seek(saveInfo.position); - for (int cnt = 0; cnt < chunkCount; cnt++) { - raFile.read(buffer, 0, BUFFER_SIZE); - os.write(buffer, 0, BUFFER_SIZE); - } - int lastChunkLength = saveInfo.size % BUFFER_SIZE; - raFile.read(buffer, 0, lastChunkLength); - os.write(buffer, 0, lastChunkLength); - } - -} diff --git a/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java b/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java deleted file mode 100644 index 775478cd4..000000000 --- a/src/java/org/apache/fop/render/afp/modca/resource/StoreInfo.java +++ /dev/null @@ -1,51 +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.resource; - -/** - * Store save information - */ -public class StoreInfo { - /** data position */ - protected long position; - - /** data chunk size */ - protected int size; - - /** name of data object */ - protected String objectName; - - /** - * Returns the object name - * - * @return the object name - */ - public String getObjectName() { - return this.objectName; - } - - /** {@inheritDoc} */ - public String toString() { - return "StoreInfo{name=" + objectName - + ", pos=" + position - + ", size=" + size - + "}"; - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/DescriptorPositionTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/DescriptorPositionTriplet.java deleted file mode 100644 index 519b4afd4..000000000 --- a/src/java/org/apache/fop/render/afp/modca/triplets/DescriptorPositionTriplet.java +++ /dev/null @@ -1,34 +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.triplets; - -/** - * A descriptor position triplet - */ -public class DescriptorPositionTriplet extends Triplet { - - /** - * Main constructor - * - * @param positionId the descriptor position id - */ - public DescriptorPositionTriplet(byte positionId) { - super(Triplet.DESCRIPTOR_POSITION, positionId); - } -}
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java index b12cc89fe..6772173de 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java @@ -5,9 +5,9 @@ * 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. @@ -30,43 +30,43 @@ import org.apache.fop.render.afp.tools.StringUtils; * The object data may or may not be defined by an IBM presentation architecture */ public class ObjectClassificationTriplet extends Triplet { - + /** * The scope of this object is the including page or overlay */ public static final byte CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT = 0x01; - + /** * The scope of this object is not defined */ public static final byte CLASS_TIME_VARIANT_PRESENTATION_OBJECT = 0x10; - + /** * This is not a presentation object, the scope of this object is not defined */ public static final byte CLASS_EXECUTABLE_PROGRAM = 0x20; - - /** + + /** * Setup information file, document level. This is not a presentation object, - */ + */ public static final byte CLASS_SETUP_FILE = 0x30; - + /** * This is a resource used by a presentation object that may itself be a resource. * The scope of the resource is the object that uses the resource. */ public static final byte CLASS_SECONDARY_RESOURCE = 0x40; - /** + /** * Data object font. This is a non-FOCA font resource used to present * text in a data object. The scope of the resource is the object that * uses the resource. */ public static final byte CLASS_DATA_OBJECT_FONT = 0x41; - + /** * Main constructor - * + * * @param objectClass * the object class type * @param objectType @@ -79,15 +79,15 @@ public class ObjectClassificationTriplet extends Triplet { // no object level or company name specified this(objectClass, objectType, strucFlgs, null, null); } - - + + private static final int OBJECT_LEVEL_LEN = 8; private static final int OBJECT_TYPE_NAME_LEN = 32; private static final int COMPANY_NAME_LEN = 32; - + /** * Fully parameterized constructor - * + * * @param objectClass * the object class type * @param objectType @@ -104,7 +104,7 @@ public class ObjectClassificationTriplet extends Triplet { super(OBJECT_CLASSIFICATION); if (objectType == null) { - throw new UnsupportedOperationException("MO:DCA Registry object type is null"); + throw new IllegalArgumentException("MO:DCA Registry object type is null"); } byte[] data = new byte[94]; @@ -112,14 +112,14 @@ public class ObjectClassificationTriplet extends Triplet { data[1] = objectClass; // ObjClass data[2] = 0x00; // reserved (must be zero) data[3] = 0x00; // reserved (must be zero) - // StrucFlgs - Information on the structure of the object container + // StrucFlgs - Information on the structure of the object container data[4] = strucFlgs.getValue(); data[5] = 0x00; // StrucFlgs - + byte[] oid = objectType.getOID(); // RegObjId - MOD:CA-registered ASN.1 OID for object type (8-23) System.arraycopy(oid, 0, data, 6, oid.length); - + // ObjTpName - name of object type (24-55) byte[] objTpName; try { @@ -129,7 +129,7 @@ public class ObjectClassificationTriplet extends Triplet { } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException("an encoding exception occurred"); } - + // ObjLev - release level or version number of object type (56-63) byte[] objectLevel; try { @@ -138,9 +138,9 @@ public class ObjectClassificationTriplet extends Triplet { } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException("an encoding exception occurred"); } - System.arraycopy(objectLevel, 0, data, 54, objectLevel.length); - - // CompName - name of company or org that owns object definition (64-95) + System.arraycopy(objectLevel, 0, data, 54, objectLevel.length); + + // CompName - name of company or organization that owns object definition (64-95) byte[] companyName; try { companyName = StringUtils.rpad(compName, ' ', COMPANY_NAME_LEN).getBytes( @@ -149,7 +149,8 @@ public class ObjectClassificationTriplet extends Triplet { throw new IllegalArgumentException("an encoding exception occurred"); } System.arraycopy(companyName, 0, data, 62, companyName.length); - + super.setData(data); } + }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/StrucFlgs.java b/src/java/org/apache/fop/render/afp/modca/triplets/StrucFlgs.java index 1478500a8..12ae5f00b 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/StrucFlgs.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/StrucFlgs.java @@ -5,9 +5,9 @@ * 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. @@ -24,46 +24,65 @@ package org.apache.fop.render.afp.modca.triplets; * information on the structure of the object and its container */ public class StrucFlgs { - private static final int OBJECT_DATA_NOT_CARRIED_IN_OBJECT_CONTAINER = 1; - private static final int OBJECT_DATA_OBJECT_CONTAINER_STRUCTURE_UNKNOWN = 2; - private static final int OBJECT_DATA_CARRIED_IN_OBJECT_CONTAINER = 3; - - private static final int OBJECT_CONTAINER_NOT_INCLUDE_OBJECT_ENVIRONMENT_GROUP = 4; + +// private static final int OBJECT_DATA_NOT_CARRIED_IN_OBJECT_CONTAINER = 1; +// private static final int OBJECT_DATA_OBJECT_CONTAINER_STRUCTURE_UNKNOWN = 2; +// private static final int OBJECT_DATA_CARRIED_IN_OBJECT_CONTAINER = 3; +// +// private static final int OBJECT_CONTAINER_NOT_INCLUDE_OBJECT_ENVIRONMENT_GROUP = 4; +// private static final int OBJECT_CONTAINER_OBJECT_ENVIRONMENT_GROUP_CONTAINMENT_UNKNOWN = 8; +// private static final int OBJECT_CONTAINER_INCLUDES_OBJECT_ENVIRONMENT_GROUP = 12; +// +// private static final int OBJECT_CONTAINER_DATA_NOT_CARRIED_IN_OBJECT_DATA = 16; +// private static final int OBJECT_CONTAINER_DATA_OBJECT_DATA_CONTAINMENT_UNKNOWN = 32; +// private static final int OBJECT_CONTAINER_DATA_CARRIES_OBJECT_DATA = 48; + + private static final int OBJECT_DATA_NOT_CARRIED_IN_OBJECT_CONTAINER = 48; + private static final int OBJECT_DATA_OBJECT_CONTAINER_STRUCTURE_UNKNOWN = 32; + private static final int OBJECT_DATA_CARRIED_IN_OBJECT_CONTAINER = 16; + + private static final int OBJECT_CONTAINER_NOT_INCLUDE_OBJECT_ENVIRONMENT_GROUP = 12; private static final int OBJECT_CONTAINER_OBJECT_ENVIRONMENT_GROUP_CONTAINMENT_UNKNOWN = 8; - private static final int OBJECT_CONTAINER_INCLUDES_OBJECT_ENVIRONMENT_GROUP = 12; - - private static final int OBJECT_CONTAINER_DATA_NOT_CARRIED_IN_OBJECT_DATA = 16; - private static final int OBJECT_CONTAINER_DATA_OBJECT_DATA_CONTAINMENT_UNKNOWN = 32; - private static final int OBJECT_CONTAINER_DATA_CARRIES_OBJECT_DATA = 48; - - private static StrucFlgs DEFAULT_STRUC_FLGS = null; + private static final int OBJECT_CONTAINER_INCLUDES_OBJECT_ENVIRONMENT_GROUP = 4; + + private static final int OBJECT_CONTAINER_DATA_NOT_CARRIED_IN_OBJECT_DATA = 3; + private static final int OBJECT_CONTAINER_DATA_OBJECT_DATA_CONTAINMENT_UNKNOWN = 2; + private static final int OBJECT_CONTAINER_DATA_CARRIES_OBJECT_DATA = 1; + + /** + * the default structured flags setting + * - data is in container with no object environment group and data in object container data + */ + public static final StrucFlgs DEFAULT = new StrucFlgs(true, false, true); + + + private int value = 0; - private byte value = 0; - /** * Main constructor + * * @param dataInContainer true if the object data in carried in the object container * @param containerHasOEG true if the object container has an object environment group - * @param dataInOCD true if the object container data carries the object data + * @param dataInOCD true if the object container data carries the object data */ public StrucFlgs(boolean dataInContainer, boolean containerHasOEG, boolean dataInOCD) { if (dataInContainer) { this.value += OBJECT_DATA_CARRIED_IN_OBJECT_CONTAINER; } else { - this.value += OBJECT_DATA_NOT_CARRIED_IN_OBJECT_CONTAINER; + this.value += OBJECT_DATA_NOT_CARRIED_IN_OBJECT_CONTAINER; } if (containerHasOEG) { this.value += OBJECT_CONTAINER_INCLUDES_OBJECT_ENVIRONMENT_GROUP; } else { - this.value += OBJECT_CONTAINER_NOT_INCLUDE_OBJECT_ENVIRONMENT_GROUP; + this.value += OBJECT_CONTAINER_NOT_INCLUDE_OBJECT_ENVIRONMENT_GROUP; } if (dataInOCD) { this.value += OBJECT_CONTAINER_DATA_CARRIES_OBJECT_DATA; } else { - this.value += OBJECT_CONTAINER_DATA_NOT_CARRIED_IN_OBJECT_DATA; + this.value += OBJECT_CONTAINER_DATA_NOT_CARRIED_IN_OBJECT_DATA; } } - + /** * Default constructor */ @@ -74,27 +93,11 @@ public class StrucFlgs { } /** + * Returns the value of structure flags value + * * @return the value of structure flags value */ public byte getValue() { - return this.value; - } - - /** - * Returns the default strucflg setting - * (data in container, container without OEG, data in OCD) - * - * @return the default strucflg settings - */ - public static StrucFlgs getDefault() { - synchronized (StrucFlgs.class) { - if (DEFAULT_STRUC_FLGS == null) { - final boolean dataInContainer = true; - final boolean containerHasOEG = false; - final boolean dataInOCD = true; - DEFAULT_STRUC_FLGS = new StrucFlgs(dataInContainer, containerHasOEG, dataInOCD); - } - } - return DEFAULT_STRUC_FLGS; + return (byte)this.value; } }
\ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java index b8c16f368..94cb36707 100644 --- a/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java +++ b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java @@ -5,9 +5,9 @@ * 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. @@ -24,50 +24,50 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import org.apache.fop.render.afp.AFPConstants; -import org.apache.fop.render.afp.modca.AbstractAFPObject; +import org.apache.fop.util.store.Streamable; /** * A simple implementation of a MOD:CA triplet */ -public class Triplet extends AbstractAFPObject { +public class Triplet implements Streamable { public static final byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01; - + /** Triplet identifiers */ - public static final byte FULLY_QUALIFIED_NAME = 0x02; - public static final byte MAPPING_OPTION = 0x04; - public static final byte OBJECT_CLASSIFICATION = 0x10; - public static final byte MODCA_INTERCHANGE_SET = 0x18; - public static final byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F; - public static final byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21; - public static final byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22; - public static final byte RESOURCE_LOCAL_IDENTIFIER = 0x24; - public static final byte RESOURCE_SECTION_NUMBER = 0x25; - public static final byte CHARACTER_ROTATION = 0x26; - public static final byte OBJECT_BYTE_OFFSET = 0x2D; - public static final byte ATTRIBUTE_VALUE = 0x36; - public static final byte DESCRIPTOR_POSITION = 0x43; - public static final byte MEDIA_EJECT_CONTROL = 0x45; - public static final byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46; - public static final byte RESOURCE_USAGE_ATTRIBUTE = 0x47; - public static final byte MEASUREMENT_UNITS = 0x4B; - public static final byte OBJECT_AREA_SIZE = 0x4C; - public static final byte AREA_DEFINITION = 0x4D; - public static final byte COLOR_SPECIFICATION = 0x4E; - public static final byte ENCODING_SCHEME_ID = 0x50; - public static final byte MEDIUM_MAP_PAGE_NUMBER = 0x56; - public static final byte OBJECT_BYTE_EXTENT = 0x57; - public static final byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58; - public static final byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59; - public static final byte OBJECT_OFFSET = 0x5A; - public static final byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D; - public static final byte OBJECT_COUNT = 0x5E; - public static final byte OBJECT_DATE_AND_TIMESTAMP = 0x62; - public static final byte COMMENT = 0x65; - public static final byte MEDIUM_ORIENTATION = 0x68; - public static final byte RESOURCE_OBJECT_INCLUDE = 0x6C; - public static final byte PRESENTATION_SPACE_RESET_MIXING = 0x70; - public static final byte PRESENTATION_SPACE_MIXING_RULE = 0x71; - public static final byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72; + public static final byte FULLY_QUALIFIED_NAME = 0x02; + public static final byte MAPPING_OPTION = 0x04; + public static final byte OBJECT_CLASSIFICATION = 0x10; + public static final byte MODCA_INTERCHANGE_SET = 0x18; + public static final byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F; + public static final byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21; + public static final byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22; + public static final byte RESOURCE_LOCAL_IDENTIFIER = 0x24; + public static final byte RESOURCE_SECTION_NUMBER = 0x25; + public static final byte CHARACTER_ROTATION = 0x26; + public static final byte OBJECT_BYTE_OFFSET = 0x2D; + public static final byte ATTRIBUTE_VALUE = 0x36; + public static final byte DESCRIPTOR_POSITION = 0x43; + public static final byte MEDIA_EJECT_CONTROL = 0x45; + public static final byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46; + public static final byte RESOURCE_USAGE_ATTRIBUTE = 0x47; + public static final byte MEASUREMENT_UNITS = 0x4B; + public static final byte OBJECT_AREA_SIZE = 0x4C; + public static final byte AREA_DEFINITION = 0x4D; + public static final byte COLOR_SPECIFICATION = 0x4E; + public static final byte ENCODING_SCHEME_ID = 0x50; + public static final byte MEDIUM_MAP_PAGE_NUMBER = 0x56; + public static final byte OBJECT_BYTE_EXTENT = 0x57; + public static final byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58; + public static final byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59; + public static final byte OBJECT_OFFSET = 0x5A; + public static final byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D; + public static final byte OBJECT_COUNT = 0x5E; + public static final byte OBJECT_DATE_AND_TIMESTAMP = 0x62; + public static final byte COMMENT = 0x65; + public static final byte MEDIUM_ORIENTATION = 0x68; + public static final byte RESOURCE_OBJECT_INCLUDE = 0x6C; + public static final byte PRESENTATION_SPACE_RESET_MIXING = 0x70; + public static final byte PRESENTATION_SPACE_MIXING_RULE = 0x71; + public static final byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72; public static final byte TONER_SAVER = 0x74; public static final byte COLOR_FIDELITY = 0x75; public static final byte FONT_FIDELITY = 0x78; @@ -89,14 +89,14 @@ public class Triplet extends AbstractAFPObject { public static final byte DEVICE_APPEARANCE = (byte)0x97; /** the triplet identifier */ - private byte id; + private final byte id; /** the triplet's data contents */ private byte[] data; /** * Main constructor - * + * * @param id the triplet identifier (see static definitions above) * @param data the data item contained in this triplet */ @@ -107,7 +107,7 @@ public class Triplet extends AbstractAFPObject { /** * Constructor - * + * * @param id the triplet identifier (see static definitions above) */ public Triplet(byte id) { @@ -116,7 +116,7 @@ public class Triplet extends AbstractAFPObject { /** * Constructor - * + * * @param id the triplet identifier (see static definitions above) * @param content the content byte data */ @@ -126,7 +126,7 @@ public class Triplet extends AbstractAFPObject { /** * Constructor - * + * * @param id the triplet identifier (see static definitions above) * @param data the data item (in String form) contained in this triplet * @throws UnsupportedEncodingException EBCIDIC encoding is not supported @@ -134,17 +134,17 @@ public class Triplet extends AbstractAFPObject { public Triplet(byte id, String data) throws UnsupportedEncodingException { this(id, data.getBytes(AFPConstants.EBCIDIC_ENCODING)); } - + /** {@inheritDoc} */ - public void write(OutputStream os) throws IOException { + public void writeToStream(OutputStream os) throws IOException { os.write((byte)data.length + 2); os.write(id); os.write(data); } - + /** * Returns the triplet identifier - * + * * @return the triplet identifier */ public byte getId() { @@ -153,7 +153,7 @@ public class Triplet extends AbstractAFPObject { /** * Sets the data contents of this triplet - * + * * @param data the data contents */ protected void setData(byte[] data) { diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java index 1e396c247..54da30436 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; @@ -873,6 +873,12 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem drawImage(url, pos); } + 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) { @@ -885,14 +891,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..6ed45ca98 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,11 +31,14 @@ import org.apache.batik.gvt.GraphicsNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.fo.extensions.ExtensionElementMapping; 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; +import org.apache.xmlgraphics.util.QName; /** * Java2D XML handler for SVG (uses Apache Batik). @@ -66,6 +71,12 @@ 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); + QName qName = new QName(ExtensionElementMapping.URI, null, "conversion-mode"); + if (foreign != null + && "bitmap".equalsIgnoreCase((String)foreign.get(qName))) { + pdfi.paintAsBitmap = true; + } return pdfi; } @@ -83,6 +94,7 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler public int currentXPosition; /** see Java2D_YPOS */ public int currentYPosition; + public boolean paintAsBitmap; /** {@inheritDoc} */ public String toString() { @@ -91,7 +103,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler + "width = " + width + ", " + "height = " + height + ", " + "currentXPosition = " + currentXPosition + ", " - + "currentYPosition = " + currentYPosition + "}"; + + "currentYPosition = " + currentYPosition + ", " + + "paintAsBitmap = " + paintAsBitmap + "}"; } } @@ -103,6 +116,18 @@ 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; @@ -126,8 +151,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(); |