import java.awt.geom.AffineTransform;
-import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.fo.Constants;
import org.apache.fop.util.ColorUtil;
/**
* Main constructor
*
- * @param state the AFP painting state converter
+ * @param paintingState the AFP painting state converter
* @param dataStream the AFP datastream
*/
- public AFPBorderPainter(AFPPaintingState state, DataStream dataStream) {
- super(state, dataStream);
+ public AFPBorderPainter(AFPPaintingState paintingState, DataStream dataStream) {
+ super(paintingState, dataStream);
}
/** {@inheritDoc} */
- public void paint(PaintInfo paintInfo) {
- BorderPaintInfo borderPaintInfo = (BorderPaintInfo)paintInfo;
+ public void paint(PaintingInfo paintInfo) {
+ BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo;
float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
if ((w < 0) || (h < 0)) {
int pageWidth = dataStream.getCurrentPage().getWidth();
int pageHeight = dataStream.getCurrentPage().getHeight();
- AFPUnitConverter unitConv = state.getUnitConverter();
- AffineTransform at = state.getData().getTransform();
+ AFPUnitConverter unitConv = paintingState.getUnitConverter();
+ AffineTransform at = paintingState.getData().getTransform();
float x1 = unitConv.pt2units(borderPaintInfo.getX1());
float y1 = unitConv.pt2units(borderPaintInfo.getY1());
float x2 = unitConv.pt2units(borderPaintInfo.getX2());
float y2 = unitConv.pt2units(borderPaintInfo.getY2());
- switch (state.getRotation()) {
+ switch (paintingState.getRotation()) {
case 0:
x1 += at.getTranslateX();
y1 += at.getTranslateY();
AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
lineDataInfo.setColor(borderPaintInfo.getColor());
- lineDataInfo.setRotation(state.getRotation());
+ lineDataInfo.setRotation(paintingState.getRotation());
lineDataInfo.x1 = Math.round(x1);
lineDataInfo.y1 = Math.round(y1);
if (borderPaintInfo.isHorizontal()) {
Rectangle2D area = graphicsObjectInfo.getArea();
g2d.scale(1, -1);
g2d.translate(0, -area.getHeight());
+
painter.paint(g2d, area);
+ graphicsObj.setComplete(true);
+
// return painted graphics object
return graphicsObj;
}
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
+import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
+import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
private static final int Y2 = 3;
+ private static final int X3 = 4;
+
+ private static final int Y3 = 5;
/** graphics object */
private GraphicsObject graphicsObj = null;
// set line width
float lineWidth = basicStroke.getLineWidth();
- getGraphicsObject().setLineWidth(Math.round(lineWidth * 2));
+ graphicsObj.setLineWidth(Math.round(lineWidth / 2));
// set line type/style (note: this is an approximation at best!)
float[] dashArray = basicStroke.getDashArray();
}
}
}
- getGraphicsObject().setLineType(type);
+ graphicsObj.setLineType(type);
}
} else {
log.warn("Unsupported Stroke: " + stroke.getClass().getName());
}
}
+ /**
+ * Apply the java paint to the AFP.
+ * This takes the java paint sets up the appropriate AFP commands
+ * for the drawing with that paint.
+ * Currently this supports the gradients and patterns from batik.
+ *
+ * @param paint the paint to convert to AFP
+ * @param fill true if the paint should be set for filling
+ * @return true if the paint is handled natively, false if the paint should be rasterized
+ */
+ private boolean applyPaint(Paint paint, boolean fill) {
+ if (paint instanceof Color) {
+ return true;
+ }
+ log.debug("NYI: applyPaint() " + paint + " fill=" + fill);
+ if (paint instanceof TexturePaint) {
+// TexturePaint texturePaint = (TexturePaint)paint;
+// BufferedImage bufferedImage = texturePaint.getImage();
+// AffineTransform at = paintingState.getTransform();
+// int x = (int)Math.round(at.getTranslateX());
+// int y = (int)Math.round(at.getTranslateY());
+// drawImage(bufferedImage, x, y, null);
+ }
+ return false;
+ }
+
+
/**
* Handle the Batik drawing event
*
graphicsObj.newSegment();
}
- Color color = getColor();
- if (paintingState.setColor(color)) {
- graphicsObj.setColor(color);
- }
+ graphicsObj.setColor(gc.getColor());
- Stroke stroke = getStroke();
- applyStroke(stroke);
+ applyPaint(gc.getPaint(), fill);
if (fill) {
graphicsObj.beginArea();
+ } else {
+ applyStroke(gc.getStroke());
}
AffineTransform trans = gc.getTransform();
PathIterator iter = shape.getPathIterator(trans);
- double[] dstPts = new double[6];
- int[] coords = null;
if (shape instanceof Line2D) {
+ double[] dstPts = new double[6];
iter.currentSegment(dstPts);
- coords = new int[4];
+ int[] coords = new int[4];
coords[X1] = (int) Math.round(dstPts[X]);
coords[Y1] = (int) Math.round(dstPts[Y]);
iter.next();
coords[Y2] = (int) Math.round(dstPts[Y]);
graphicsObj.addLine(coords);
} else if (shape instanceof Rectangle2D) {
+ double[] dstPts = new double[6];
iter.currentSegment(dstPts);
- coords = new int[4];
+ int[] coords = new int[4];
coords[X2] = (int) Math.round(dstPts[X]);
coords[Y2] = (int) Math.round(dstPts[Y]);
iter.next();
coords[Y1] = (int) Math.round(dstPts[Y]);
graphicsObj.addBox(coords);
} else if (shape instanceof Ellipse2D) {
+ double[] dstPts = new double[6];
Ellipse2D elip = (Ellipse2D) shape;
double scale = trans.getScaleX();
double radiusWidth = elip.getWidth() / 2;
mhr
);
} else {
- for (int[] openingCoords = new int[2]; !iter.isDone(); iter.next()) {
- int type = iter.currentSegment(dstPts);
- int numCoords;
- if (type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO) {
- numCoords = 2;
- } else if (type == PathIterator.SEG_QUADTO) {
- numCoords = 4;
- } else if (type == PathIterator.SEG_CUBICTO) {
- numCoords = 6;
- } else {
- // close of the graphics segment
- if (type == PathIterator.SEG_CLOSE) {
- // close segment by drawing to opening position
- graphicsObj.addLine(openingCoords, true);
- } else {
- log.debug("Unrecognised path iterator type: "
- + type);
- }
- continue;
- }
- coords = new int[numCoords];
- for (int i = 0; i < numCoords; i++) {
- coords[i] = (int) Math.round(dstPts[i]);
- }
- if (type == PathIterator.SEG_MOVETO) {
- graphicsObj.setCurrentPosition(coords);
- openingCoords[X] = coords[X];
- openingCoords[Y] = coords[Y];
- } else if (type == PathIterator.SEG_LINETO) {
- graphicsObj.addLine(coords, true);
- } else if (type == PathIterator.SEG_QUADTO
- || type == PathIterator.SEG_CUBICTO) {
- graphicsObj.addFillet(coords, true);
- }
- }
+ processPathIterator(iter);
}
+
if (fill) {
graphicsObj.endArea();
}
}
+ /**
+ * Processes a path iterator generating the necessary painting operations.
+ *
+ * @param iter PathIterator to process
+ */
+ private void processPathIterator(PathIterator iter) {
+ double[] dstPts = new double[6];
+ for (int[] openingCoords = new int[2]; !iter.isDone(); iter.next()) {
+ switch (iter.currentSegment(dstPts)) {
+ case PathIterator.SEG_LINETO:
+ graphicsObj.addLine(new int[] {
+ (int)Math.round(dstPts[X]),
+ (int)Math.round(dstPts[Y])
+ }, true);
+ break;
+ case PathIterator.SEG_QUADTO:
+ graphicsObj.addFillet(new int[] {
+ (int)Math.round(dstPts[X1]),
+ (int)Math.round(dstPts[Y1]),
+ (int)Math.round(dstPts[X2]),
+ (int)Math.round(dstPts[Y2])
+ }, true);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ graphicsObj.addFillet(new int[] {
+ (int)Math.round(dstPts[X1]),
+ (int)Math.round(dstPts[Y1]),
+ (int)Math.round(dstPts[X2]),
+ (int)Math.round(dstPts[Y2]),
+ (int)Math.round(dstPts[X3]),
+ (int)Math.round(dstPts[Y3])
+ }, true);
+ break;
+ case PathIterator.SEG_MOVETO:
+ openingCoords = new int[] {
+ (int)Math.round(dstPts[X]),
+ (int)Math.round(dstPts[Y])
+ };
+ graphicsObj.setCurrentPosition(openingCoords);
+ break;
+ case PathIterator.SEG_CLOSE:
+ graphicsObj.addLine(openingCoords, true);
+ break;
+ default:
+ log.debug("Unrecognised path iterator type");
+ break;
+ }
+ }
+ }
+
/** {@inheritDoc} */
public void draw(Shape shape) {
-// log.debug("draw() shape=" + shape);
+ log.debug("draw() shape=" + shape);
doDrawing(shape, false);
}
/** {@inheritDoc} */
public void fill(Shape shape) {
-// log.debug("fill() shape=" + shape);
+ log.debug("fill() shape=" + shape);
doDrawing(shape, true);
}
return graphicsConfig;
}
- /** {@inheritDoc} */
- public void copyArea(int x, int y, int width, int height, int dx, int dy) {
- log.debug("copyArea() NYI: ");
- }
-
/** {@inheritDoc} */
public Graphics create() {
return new AFPGraphics2D(this);
log.debug("NYI: addNativeImage() "+ "image=" + image
+ ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height);
}
+
+ /** {@inheritDoc} */
+ public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+ log.debug("copyArea() NYI: ");
+ }
}
/**
* This keeps information about the current painting state when writing to an AFP datastream.
*/
-public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState implements Cloneable {
+public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
+implements Cloneable {
private static final long serialVersionUID = 8206711712452344473L;
/** {@inheritDoc} */
public Object clone() {
- AFPPaintingState state = (AFPPaintingState)super.clone();
- state.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
- state.portraitRotation = this.portraitRotation;
- state.landscapeRotation = this.landscapeRotation;
- state.bitsPerPixel = this.bitsPerPixel;
- state.colorImages = this.colorImages;
- state.resolution = this.resolution;
- return state;
+ AFPPaintingState paintingState = (AFPPaintingState)super.clone();
+ paintingState.pagePaintingState = (AFPPagePaintingState)this.pagePaintingState.clone();
+ paintingState.portraitRotation = this.portraitRotation;
+ paintingState.landscapeRotation = this.landscapeRotation;
+ paintingState.bitsPerPixel = this.bitsPerPixel;
+ paintingState.colorImages = this.colorImages;
+ paintingState.resolution = this.resolution;
+ return paintingState;
}
/** {@inheritDoc} */
import java.awt.geom.AffineTransform;
-import org.apache.fop.afp.modca.DataStream;
+/**
+ * A painter of rectangles in AFP
+ */
public class AFPRectanglePainter extends AbstractAFPPainter {
/**
* Main constructor
*
- * @param state the AFP painting state
- * @param dataStream the afp datastream
+ * @param paintingState the AFP painting state
+ * @param dataStream the AFP datastream
*/
- public AFPRectanglePainter(AFPPaintingState state, DataStream dataStream) {
- super(state, dataStream);
+ public AFPRectanglePainter(AFPPaintingState paintingState, DataStream dataStream) {
+ super(paintingState, dataStream);
}
/** {@inheritDoc} */
- public void paint(PaintInfo paintInfo) {
- RectanglePaintInfo rectanglePaintInfo = (RectanglePaintInfo)paintInfo;
+ public void paint(PaintingInfo paintInfo) {
+ RectanglePaintingInfo rectanglePaintInfo = (RectanglePaintingInfo)paintInfo;
int pageWidth = dataStream.getCurrentPage().getWidth();
int pageHeight = dataStream.getCurrentPage().getHeight();
- AFPUnitConverter unitConv = state.getUnitConverter();
+ AFPUnitConverter unitConv = paintingState.getUnitConverter();
float width = unitConv.pt2units(rectanglePaintInfo.getWidth());
float height = unitConv.pt2units(rectanglePaintInfo.getHeight());
float x = unitConv.pt2units(rectanglePaintInfo.getX());
float y = unitConv.pt2units(rectanglePaintInfo.getY());
- AffineTransform at = state.getData().getTransform();
+ AffineTransform at = paintingState.getData().getTransform();
AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
- lineDataInfo.color = state.getColor();
- lineDataInfo.rotation = state.getRotation();
+ lineDataInfo.color = paintingState.getColor();
+ lineDataInfo.rotation = paintingState.getRotation();
lineDataInfo.thickness = Math.round(height);
switch (lineDataInfo.rotation) {
import org.apache.fop.afp.modca.AbstractDataObject;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.afp.modca.IncludeObject;
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.StreamedResourceGroup;
public class AFPUnitConverter {
/** the AFP state */
- private final AFPPaintingState state;
+ private final AFPPaintingState paintingState;
/**
* Unit converter
*
- * @param state the AFP painting state
+ * @param paintingState the AFP painting state
*/
- public AFPUnitConverter(AFPPaintingState state) {
- this.state = state;
+ public AFPUnitConverter(AFPPaintingState paintingState) {
+ this.paintingState = paintingState;
}
/**
* @return transformed point
*/
public float pt2units(float pt) {
- return pt / ((float)AFPConstants.DPI_72 / state.getResolution());
+ return pt / ((float)AFPConstants.DPI_72 / paintingState.getResolution());
}
/**
* @return transformed point
*/
public float mpt2units(float mpt) {
- return mpt / ((float)AFPConstants.DPI_72_MPTS / state.getResolution());
+ return mpt / ((float)AFPConstants.DPI_72_MPTS / paintingState.getResolution());
}
private int[] transformPoints(float[] srcPts, float[] dstPts, boolean milli) {
if (dstPts == null) {
dstPts = new float[srcPts.length];
}
- AffineTransform at = state.getData().getTransform();
+ AffineTransform at = paintingState.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++) {
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.afp.modca.DataStream;
+/**
+ * A base AFP painter
+ */
public abstract class AbstractAFPPainter {
/** Static logging instance */
protected static Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
protected final DataStream dataStream;
- protected final AFPPaintingState state;
+ protected final AFPPaintingState paintingState;
/**
* Main constructor
*
- * @param state the afp state
- * @param dataStream the afp datastream
+ * @param paintingState the AFP painting state
+ * @param dataStream the AFP Datastream
*/
- public AbstractAFPPainter(AFPPaintingState state, DataStream dataStream) {
- this.state = state;
+ public AbstractAFPPainter(AFPPaintingState paintingState, DataStream dataStream) {
+ this.paintingState = paintingState;
this.dataStream = dataStream;
}
*
* @param paintInfo the painting information
*/
- public abstract void paint(PaintInfo paintInfo);
+ public abstract void paint(PaintingInfo paintInfo);
}
+++ /dev/null
-/*
- * 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.afp;
-
-import java.awt.Color;
-
-
-/**
- * Border painting information
- */
-public class BorderPaintInfo implements PaintInfo {
- private final float x1;
- private final float y1;
- private final float x2;
- private final float y2;
- private final boolean isHorizontal;
- private final int style;
- private final Color color;
-
- /**
- * Main constructor
- *
- * @param x1 the x1 coordinate
- * @param y1 the y1 coordinate
- * @param x2 the x2 coordinate
- * @param y2 the y2 coordinate
- * @param isHorizontal true when the border line is horizontal
- * @param style the border style
- * @param color the border color
- */
- public BorderPaintInfo(float x1, float y1, float x2, float y2,
- boolean isHorizontal, int style, Color color) {
- this.x1 = x1;
- this.y1 = y1;
- this.x2 = x2;
- this.y2 = y2;
- this.isHorizontal = isHorizontal;
- this.style = style;
- this.color = color;
- }
-
- /**
- * Returns the x1 coordinate
- *
- * @return the x1 coordinate
- */
- public float getX1() {
- return x1;
- }
-
- /**
- * Returns the y1 coordinate
- *
- * @return the y1 coordinate
- */
- public float getY1() {
- return y1;
- }
-
- /**
- * Returns the x2 coordinate
- *
- * @return the x2 coordinate
- */
- public float getX2() {
- return x2;
- }
-
- /**
- * Returns the y2 coordinate
- *
- * @return the y2 coordinate
- */
- public float getY2() {
- return y2;
- }
-
- /**
- * Returns true when this is a horizontal line
- *
- * @return true when this is a horizontal line
- */
- public boolean isHorizontal() {
- return isHorizontal;
- }
-
- /**
- * Returns the style
- *
- * @return the style
- */
- public int getStyle() {
- return style;
- }
-
- /**
- * Returns the color
- *
- * @return the color
- */
- public Color getColor() {
- return color;
- }
-}
--- /dev/null
+/*
+ * 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.afp;
+
+import java.awt.Color;
+
+/**
+ * Border painting information
+ */
+public class BorderPaintingInfo implements PaintingInfo {
+
+ private final float x1;
+ private final float y1;
+ private final float x2;
+ private final float y2;
+ private final boolean isHorizontal;
+ private final int style;
+ private final Color color;
+
+ /**
+ * Main constructor
+ *
+ * @param x1 the x1 coordinate
+ * @param y1 the y1 coordinate
+ * @param x2 the x2 coordinate
+ * @param y2 the y2 coordinate
+ * @param isHorizontal true when the border line is horizontal
+ * @param style the border style
+ * @param color the border color
+ */
+ public BorderPaintingInfo(float x1, float y1, float x2, float y2,
+ boolean isHorizontal, int style, Color color) {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ this.isHorizontal = isHorizontal;
+ this.style = style;
+ this.color = color;
+ }
+
+ /**
+ * Returns the x1 coordinate
+ *
+ * @return the x1 coordinate
+ */
+ public float getX1() {
+ return x1;
+ }
+
+ /**
+ * Returns the y1 coordinate
+ *
+ * @return the y1 coordinate
+ */
+ public float getY1() {
+ return y1;
+ }
+
+ /**
+ * Returns the x2 coordinate
+ *
+ * @return the x2 coordinate
+ */
+ public float getX2() {
+ return x2;
+ }
+
+ /**
+ * Returns the y2 coordinate
+ *
+ * @return the y2 coordinate
+ */
+ public float getY2() {
+ return y2;
+ }
+
+ /**
+ * Returns true when this is a horizontal line
+ *
+ * @return true when this is a horizontal line
+ */
+ public boolean isHorizontal() {
+ return isHorizontal;
+ }
+
+ /**
+ * Returns the style
+ *
+ * @return the style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Returns the color
+ *
+ * @return the color
+ */
+ public Color getColor() {
+ return color;
+ }
+}
--- /dev/null
+/*
+ * 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.afp;
+
+/**
+ * Set and expose the internal completeness of an object.
+ */
+public interface Completable {
+
+ /**
+ * Sets whether or not this object is complete or not
+ *
+ * @param complete true if this object is complete
+ */
+ void setComplete(boolean complete);
+
+ /**
+ * Returns true if this object is complete
+ *
+ * @return true if this object is complete
+ */
+ boolean isComplete();
+}
--- /dev/null
+/*
+ * 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.afp;
+
+import java.awt.Color;
+import java.awt.Point;
+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.afp.fonts.AFPFont;
+import org.apache.fop.afp.fonts.AFPFontAttributes;
+import org.apache.fop.afp.modca.AbstractPageObject;
+import org.apache.fop.afp.modca.Document;
+import org.apache.fop.afp.modca.InterchangeSet;
+import org.apache.fop.afp.modca.Overlay;
+import org.apache.fop.afp.modca.PageGroup;
+import org.apache.fop.afp.modca.PageObject;
+import org.apache.fop.afp.modca.ResourceGroup;
+import org.apache.fop.afp.modca.TagLogicalElementBean;
+import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
+
+/**
+ * A data stream is a continuous ordered stream of data elements and objects
+ * conforming to a given format. Application programs can generate data streams
+ * destined for a presentation service, archive library, presentation device or
+ * another application program. The strategic presentation data stream
+ * architectures used is Mixed Object Document Content Architecture (MO:DCA).
+ *
+ * The MO:DCA architecture defines the data stream used by applications to
+ * describe documents and object envelopes for interchange with other
+ * applications and application services. Documents defined in the MO:DCA format
+ * may be archived in a database, then later retrieved, viewed, annotated and
+ * printed in local or distributed systems environments. Presentation fidelity
+ * is accommodated by including resource objects in the documents that reference
+ * them.
+ */
+public class DataStream {
+
+ /** Static logging instance */
+ protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp");
+
+ /** Boolean completion indicator */
+ private boolean complete = false;
+
+ /** The AFP document object */
+ private Document document = null;
+
+ /** The current page group object */
+ private PageGroup currentPageGroup = null;
+
+ /** The current page object */
+ private PageObject currentPageObject = null;
+
+ /** The current overlay object */
+ private Overlay currentOverlay = null;
+
+ /** The current page */
+ private AbstractPageObject currentPage = null;
+
+ /** The 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 final Factory factory;
+
+ private OutputStream outputStream;
+
+ /** the afp painting state */
+ private final AFPPaintingState paintingState;
+
+ /**
+ * Default constructor for the AFPDocumentStream.
+ *
+ * @param factory the resource factory
+ * @param paintingState the AFP painting state
+ * @param outputStream the outputstream to write to
+ */
+ public DataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) {
+ this.paintingState = paintingState;
+ 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() {
+ return this.document;
+ }
+
+ /**
+ * Returns the current page
+ *
+ * @return the current page
+ */
+ public AbstractPageObject getCurrentPage() {
+ return this.currentPage;
+ }
+
+ /**
+ * The document is started by invoking this method which creates an instance
+ * of the AFP Document object.
+ *
+ * @param name
+ * the name of this document.
+ */
+ public void setDocumentName(String name) {
+ if (name != null) {
+ getDocument().setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR, name);
+ }
+ }
+
+ /**
+ * Helper method to mark the end of the current document.
+ *
+ * @throws IOException thrown if an I/O exception of some sort has occurred
+ */
+ public void endDocument() throws IOException {
+ if (complete) {
+ String msg = "Invalid state - document already ended.";
+ log.warn("endDocument():: " + msg);
+ throw new IllegalStateException(msg);
+ }
+
+ if (currentPageObject != null) {
+ // End the current page if necessary
+ endPage();
+ }
+
+ if (currentPageGroup != null) {
+ // End the current page group if necessary
+ endPageGroup();
+ }
+
+ // Write out document
+ if (document != null) {
+ document.endDocument();
+ document.writeToStream(this.outputStream);
+ }
+
+ this.outputStream.flush();
+
+ this.complete = true;
+
+ this.document = null;
+
+ this.outputStream = null;
+ }
+
+ /**
+ * Start a new page. When processing has finished on the current page, the
+ * {@link #endPage()}method must be invoked to mark the page ending.
+ *
+ * @param pageWidth
+ * the width of the page
+ * @param pageHeight
+ * the height of the page
+ * @param pageRotation
+ * the rotation of the page
+ * @param pageWidthRes
+ * the width resolution of the page
+ * @param pageHeightRes
+ * the height resolution of the page
+ */
+ public void startPage(int pageWidth, int pageHeight, int pageRotation,
+ int pageWidthRes, int pageHeightRes) {
+ currentPageObject = factory.createPage(pageWidth, pageHeight,
+ pageRotation, pageWidthRes, pageHeightRes);
+ currentPage = currentPageObject;
+ currentOverlay = null;
+ }
+
+ /**
+ * Start a new overlay. When processing has finished on the current overlay,
+ * the {@link #endOverlay()}method must be invoked to mark the overlay
+ * ending.
+ *
+ * @param x
+ * the x position of the overlay on the page
+ * @param y
+ * the y position of the overlay on the page
+ * @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
+ */
+ public void startOverlay(int x, int y, int width, int height, int widthRes,
+ int heightRes, int overlayRotation) {
+ this.currentOverlay = factory.createOverlay(
+ width, height, widthRes, heightRes, overlayRotation);
+
+ String overlayName = currentOverlay.getName();
+ currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
+ currentPage = currentOverlay;
+ }
+
+ /**
+ * 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() throws IOException {
+ if (currentOverlay != null) {
+ currentOverlay.endPage();
+ currentOverlay = null;
+ currentPage = currentPageObject;
+ }
+ }
+
+ /**
+ * Helper method to save the current page.
+ *
+ * @return current page object that was saved
+ */
+ public PageObject savePage() {
+ PageObject pageObject = currentPageObject;
+ if (currentPageGroup != null) {
+ currentPageGroup.addPage(currentPageObject);
+ } else {
+ document.addPage(currentPageObject);
+ }
+ currentPageObject = null;
+ currentPage = null;
+ return pageObject;
+ }
+
+ /**
+ * Helper method to restore the current page.
+ *
+ * @param pageObject
+ * page object
+ */
+ public void restorePage(PageObject pageObject) {
+ currentPageObject = pageObject;
+ currentPage = pageObject;
+ }
+
+ /**
+ * Helper method to mark the end of the current page.
+ *
+ * @throws IOException thrown if an I/O exception of some sort has occurred
+ */
+ 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;
+ }
+ }
+
+ /**
+ * Creates the given page fonts in the current page
+ *
+ * @param pageFonts
+ * a collection of AFP font attributes
+ */
+ public void addFontsToCurrentPage(Map pageFonts) {
+ Iterator iter = pageFonts.values().iterator();
+ while (iter.hasNext()) {
+ AFPFontAttributes afpFontAttributes = (AFPFontAttributes) iter
+ .next();
+ createFont(afpFontAttributes.getFontReference(), afpFontAttributes
+ .getFont(), afpFontAttributes.getPointSize());
+ }
+ }
+
+ /**
+ * Helper method to create a map coded font object on the current page, this
+ * method delegates the construction of the map coded font object to the
+ * active environment group on the current page.
+ *
+ * @param fontReference
+ * the font number used as the resource identifier
+ * @param font
+ * the font
+ * @param size
+ * the point size of the font
+ */
+ public void createFont(int fontReference, AFPFont font, int size) {
+ currentPage.createFont(fontReference, font, size);
+ }
+
+ /**
+ * Returns a point on the current page
+ *
+ * @param x the X-coordinate
+ * @param y the Y-coordinate
+ * @return a point on the current page
+ */
+ private Point getPoint(int x, int y) {
+ Point p = new Point();
+ int rotation = paintingState.getRotation();
+ switch (rotation) {
+ case 90:
+ p.x = y;
+ p.y = currentPage.getWidth() - x;
+ break;
+ case 180:
+ p.x = currentPage.getWidth() - x;
+ p.y = currentPage.getHeight() - y;
+ break;
+ case 270:
+ p.x = currentPage.getHeight() - y;
+ p.y = x;
+ break;
+ default:
+ p.x = x;
+ p.y = y;
+ break;
+ }
+ return p;
+ }
+
+ /**
+ * Helper method to create text on the current page, this method delegates
+ * to the current presentation text object in order to construct the text.
+ *
+ * @param textDataInfo
+ * the afp text data
+ */
+ public void createText(AFPTextDataInfo textDataInfo) {
+ int rotation = paintingState.getRotation();
+ if (rotation != 0) {
+ textDataInfo.setRotation(rotation);
+ Point p = getPoint(textDataInfo.getX(), textDataInfo.getY());
+ textDataInfo.setX(p.x);
+ textDataInfo.setY(p.y);
+ }
+ currentPage.createText(textDataInfo);
+ }
+
+ /**
+ * Method to create a line on the current page.
+ *
+ * @param lineDataInfo the line data information.
+ */
+ public void createLine(AFPLineDataInfo lineDataInfo) {
+ currentPage.createLine(lineDataInfo);
+ }
+
+ /**
+ * This method will create shading on the page using the specified
+ * coordinates (the shading contrast is controlled via the red, green, blue
+ * parameters, by converting this to grey scale).
+ *
+ * @param x
+ * the x coordinate of the shading
+ * @param y
+ * the y coordinate of the shading
+ * @param w
+ * the width of the shaded area
+ * @param h
+ * the height of the shaded area
+ * @param col
+ * the shading color
+ */
+ public void createShading(int x, int y, int w, int h, Color col) {
+ currentPageObject.createShading(x, y, w, h, col.getRed(), col.getGreen(), col.getBlue());
+ }
+
+ /**
+ * Helper method which allows creation of the MPO object, via the AEG. And
+ * the IPO via the Page. (See actual object for descriptions.)
+ *
+ * @param name
+ * the name of the static overlay
+ */
+ public void createIncludePageOverlay(String name) {
+ currentPageObject.createIncludePageOverlay(name, 0, 0, paintingState.getRotation());
+ currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
+ }
+
+ /**
+ * Helper method which allows creation of the IMM object.
+ *
+ * @param name
+ * the name of the medium map
+ */
+ public void createInvokeMediumMap(String name) {
+ currentPageGroup.createInvokeMediumMap(name);
+ }
+
+ /**
+ * Creates an IncludePageSegment on the current page.
+ *
+ * @param name
+ * the name of the include page segment
+ * @param x
+ * the x coordinate for the overlay
+ * @param y
+ * the y coordinate for the overlay
+ */
+ public void createIncludePageSegment(String name, int x, int y) {
+ int xOrigin;
+ int yOrigin;
+ int orientation = paintingState.getRotation();
+ switch (orientation) {
+ case 90:
+ xOrigin = currentPage.getWidth() - y;
+ yOrigin = x;
+ break;
+ case 180:
+ xOrigin = currentPage.getWidth() - x;
+ yOrigin = currentPage.getHeight() - y;
+ break;
+ case 270:
+ xOrigin = y;
+ yOrigin = currentPage.getHeight() - x;
+ break;
+ default:
+ xOrigin = x;
+ yOrigin = y;
+ break;
+ }
+ currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page.
+ *
+ * @param attributes
+ * the array of key value pairs.
+ */
+ public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ String name = attributes[i].getKey();
+ String value = attributes[i].getValue();
+ currentPage.createTagLogicalElement(name, value);
+ }
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page group.
+ *
+ * @param attributes
+ * the array of key value pairs.
+ */
+ public void createPageGroupTagLogicalElement(TagLogicalElementBean[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ String name = attributes[i].getKey();
+ String value = attributes[i].getValue();
+ currentPageGroup.createTagLogicalElement(name, value);
+ }
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page or page group
+ *
+ * @param name
+ * The tag name
+ * @param value
+ * The tag value
+ */
+ public void createTagLogicalElement(String name, String value) {
+ if (currentPageGroup != null) {
+ currentPageGroup.createTagLogicalElement(name, value);
+ } else {
+ currentPage.createTagLogicalElement(name, value);
+ }
+ }
+
+ /**
+ * Creates a NoOperation item
+ *
+ * @param content
+ * byte data
+ */
+ public void createNoOperation(String content) {
+ currentPage.createNoOperation(content);
+ }
+
+ /**
+ * Returns the current page group
+ *
+ * @return the current page group
+ */
+ 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() 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() throws IOException {
+ if (currentPageGroup != null) {
+ currentPageGroup.endPageGroup();
+ document.addPageGroup(currentPageGroup);
+ document.writeToStream(outputStream);
+ currentPageGroup = null;
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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.isDocument()) {
+ resourceGroup = document.getResourceGroup();
+ } else if (level.isPageGroup()) {
+ resourceGroup = currentPageGroup.getResourceGroup();
+ } else if (level.isPage()) {
+ resourceGroup = currentPageObject.getResourceGroup();
+ }
+ return resourceGroup;
+ }
+
+}
import org.apache.fop.afp.ioca.ImageSizeParameter;
import org.apache.fop.afp.modca.ActiveEnvironmentGroup;
import org.apache.fop.afp.modca.ContainerDataDescriptor;
-import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.afp.modca.Document;
import org.apache.fop.afp.modca.GraphicsDataDescriptor;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.afp.util.StringUtils;
/**
- * Creator of MO:DCA data objects (mostly)
+ * Creator of MO:DCA structured field objects
*/
public class Factory {
/**
* Creates a new {@link DataStream}
*
- * @param state the AFP painting state
+ * @param paintingState the AFP painting state
* @param outputStream an outputstream to write to
* @return a new {@link DataStream}
*/
- public DataStream createDataStream(AFPPaintingState state, OutputStream outputStream) {
- DataStream dataStream = new DataStream(this, state, outputStream);
+ public DataStream createDataStream(AFPPaintingState paintingState, OutputStream outputStream) {
+ DataStream dataStream = new DataStream(this, paintingState, outputStream);
return dataStream;
}
+++ /dev/null
-/*
- * 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.afp;
-
-/**
- * Generic painting information interface
- */
-public interface PaintInfo {
-
-}
--- /dev/null
+/*
+ * 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.afp;
+
+/**
+ * Generic painting information interface
+ */
+public interface PaintingInfo {
+
+}
+++ /dev/null
-/*
- * 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.afp;
-
-
-/**
- * Filled rectangle painting information
- */
-public class RectanglePaintInfo implements PaintInfo {
-
- private final float x;
- private final float y;
- private final float width;
- private final float height;
-
- /**
- * Main constructor
- *
- * @param x the x coordinate
- * @param y the y coordinate
- * @param width the width
- * @param height the height
- */
- public RectanglePaintInfo(float x, float y, float width, float height) {
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- }
-
- /**
- * Returns the x coordinate
- *
- * @return the x coordinate
- */
- protected float getX() {
- return x;
- }
-
- /**
- * Returns the y coordinate
- *
- * @return the y coordinate
- */
- protected float getY() {
- return y;
- }
-
- /**
- * Returns the width
- *
- * @return the width
- */
- protected float getWidth() {
- return width;
- }
-
- /**
- * Returns the height
- *
- * @return the height
- */
- protected float getHeight() {
- return height;
- }
-
-}
--- /dev/null
+/*
+ * 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.afp;
+
+
+/**
+ * Filled rectangle painting information
+ */
+public class RectanglePaintingInfo implements PaintingInfo {
+
+ private final float x;
+ private final float y;
+ private final float width;
+ private final float height;
+
+ /**
+ * Main constructor
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param width the width
+ * @param height the height
+ */
+ public RectanglePaintingInfo(float x, float y, float width, float height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Returns the x coordinate
+ *
+ * @return the x coordinate
+ */
+ protected float getX() {
+ return x;
+ }
+
+ /**
+ * Returns the y coordinate
+ *
+ * @return the y coordinate
+ */
+ protected float getY() {
+ return y;
+ }
+
+ /**
+ * Returns the width
+ *
+ * @return the width
+ */
+ protected float getWidth() {
+ return width;
+ }
+
+ /**
+ * Returns the height
+ *
+ * @return the height
+ */
+ protected float getHeight() {
+ return height;
+ }
+
+}
--- /dev/null
+/*
+ * 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.afp;
+
+/**
+ * Set and expose whether an object has started or not.
+ */
+public interface Startable {
+
+ /**
+ * Sets whether or not this object has started or not
+ *
+ * @param complete true if this object has started
+ */
+ void setStarted(boolean started);
+
+ /**
+ * Returns true if this object has started
+ *
+ * @return true if this object has started
+ */
+ boolean isStarted();
+}
--- /dev/null
+/*
+ * 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.afp;
+
+/**
+ * An AFP object which is able to know its own data length prior to writeToStream()
+ */
+public interface StructuredData {
+
+ /**
+ * Returns the data length of this structured field
+ *
+ * @return the data length of this structured field
+ */
+ int getDataLength();
+}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
import org.apache.fop.afp.util.BinaryUtils;
/**
* A base class encapsulating the structure of coordinate based GOCA objects
*/
-public abstract class AbstractGraphicsCoord extends AbstractNamedAFPObject
- implements StructuredDataObject {
+public abstract class AbstractGraphicsCoord extends AbstractGraphicsDrawingOrder {
/** array of x/y coordinates */
protected int[] coords = null;
+ protected boolean relative = false;
+
/**
* Constructor
*
* @param coords the x/y coordinates for this object
*/
public AbstractGraphicsCoord(int[] coords) {
- this.coords = coords;
+ if (coords == null) {
+ relative = true;
+ } else {
+ this.coords = coords;
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param coords the x/y coordinates for this object
+ * @param relative
+ */
+ public AbstractGraphicsCoord(int[] coords, boolean relative) {
+ this(coords);
+ this.relative = relative;
}
/**
/** {@inheritDoc} */
public int getDataLength() {
- return 2 + (coords.length * 2);
+ return 2 + (coords != null ? coords.length * 2 : 0);
}
- /**
- * Returns the order code of this structured field
- *
- * @return the order code of this structured field
- */
- abstract byte getOrderCode();
-
/**
* Returns the coordinate data start index
*
* @return the coordinate data
*/
byte[] getData() {
- int len = getDataLength();
- byte[] data = new byte[len];
- data[0] = getOrderCode();
- data[1] = (byte)(len - 2);
-
+ byte[] data = super.getData();
if (coords != null) {
addCoords(data, getCoordinateDataStartIndex());
}
-
return data;
}
}
}
- /**
- * Returns the short name of this GOCA object
- *
- * @return the short name of this GOCA object
- */
- public String getName() {
- String className = getClass().getName();
- return className.substring(className.lastIndexOf(".") + 1);
- }
-
/** {@inheritDoc} */
public String toString() {
String coordsStr = "";
coordsStr = coordsStr.substring(0, coordsStr.length() - 1);
return getName() + "{" + coordsStr + "}";
}
+
+ /**
+ * Returns true if this is a relative drawing order
+ *
+ * @return true if this is a relative drawing order
+ */
+ protected boolean isRelative() {
+ return this.relative;
+ }
}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.afp.goca;
+
+import org.apache.fop.afp.StructuredData;
+import org.apache.fop.afp.modca.AbstractAFPObject;
+
+/**
+ * A base GOCA drawing order
+ */
+public abstract class AbstractGraphicsDrawingOrder extends AbstractAFPObject
+ implements StructuredData {
+
+ /**
+ * Returns the order code of this structured field
+ *
+ * @return the order code of this structured field
+ */
+ abstract byte getOrderCode();
+
+ /**
+ * Returns the coordinate data
+ *
+ * @return the coordinate data
+ */
+ byte[] getData() {
+ int len = getDataLength();
+ byte[] data = new byte[len];
+ data[0] = getOrderCode();
+ data[1] = (byte)(len - 2);
+ return data;
+ }
+
+ /**
+ * Returns the short name of this GOCA object
+ *
+ * @return the short name of this GOCA object
+ */
+ public String getName() {
+ String className = getClass().getName();
+ return className.substring(className.lastIndexOf(".") + 1);
+ }
+}
--- /dev/null
+/*
+ * 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.afp.goca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.afp.Completable;
+import org.apache.fop.afp.Startable;
+import org.apache.fop.afp.StructuredData;
+import org.apache.fop.afp.modca.AbstractNamedAFPObject;
+
+/**
+ * A base container of prepared structured AFP objects
+ */
+public abstract class AbstractGraphicsDrawingOrderContainer extends AbstractNamedAFPObject
+implements StructuredData, Completable, Startable {
+
+ /** list of objects contained within this container */
+ protected List/*<StructuredDataObject>*/ objects
+ = new java.util.ArrayList/*<StructuredDataObject>*/();
+
+ /** object is complete */
+ private boolean complete = false;
+
+ /** object has started */
+ private boolean started = false;
+
+ /**
+ * Default constructor
+ */
+ protected AbstractGraphicsDrawingOrderContainer() {
+ }
+
+ /**
+ * Named constructor
+ *
+ * @param name the name of the container
+ */
+ protected AbstractGraphicsDrawingOrderContainer(String name) {
+ super(name);
+ }
+
+ /** {@inheritDoc} */
+ protected void writeStart(OutputStream os) throws IOException {
+ setStarted(true);
+ }
+
+ /** {@inheritDoc} */
+ protected void writeContent(OutputStream os) throws IOException {
+ writeObjects(objects, os);
+ }
+
+ /**
+ * Adds a given graphics object to this container
+ *
+ * @param object the structured data object
+ */
+ public void addObject(StructuredData object) {
+ objects.add(object);
+ }
+
+ /**
+ * Adds all the contents of a given graphics container to this container
+ *
+ * @param graphicsContainer a graphics container
+ */
+ public void addAll(AbstractGraphicsDrawingOrderContainer graphicsContainer) {
+ Collection/*<StructuredDataObject>*/ objects = graphicsContainer.getObjects();
+ objects.addAll(objects);
+ }
+
+ /**
+ * Returns all the objects in this container
+ *
+ * @return all the objects in this container
+ */
+ private Collection getObjects() {
+ return this.objects;
+ }
+
+ /**
+ * Removes the last drawing order from this container and returns it
+ *
+ * @return the last drawing order from this container or null if empty
+ */
+ public StructuredData removeLast() {
+ int lastIndex = objects.size() - 1;
+ StructuredData object = null;
+ if (lastIndex > -1) {
+ object = (StructuredData)objects.get(lastIndex);
+ objects.remove(lastIndex);
+ }
+ return object;
+ }
+
+ /**
+ * Returns the current data length
+ *
+ * @return the current data length of this container including
+ * all enclosed objects (and their containers)
+ */
+ public int getDataLength() {
+ int dataLen = 0;
+ Iterator it = objects.iterator();
+ while (it.hasNext()) {
+ dataLen += ((StructuredData)it.next()).getDataLength();
+ }
+ return dataLen;
+ }
+
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ Iterator it = objects.iterator();
+ while (it.hasNext()) {
+ Object object = it.next();
+ if (object instanceof Completable) {
+ ((Completable)object).setComplete(true);
+ }
+ }
+ this.complete = true;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isComplete() {
+ return this.complete;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isStarted() {
+ return this.started;
+ }
+
+ /** {@inheritDoc} */
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+}
+++ /dev/null
-/*
- * 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.afp.goca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
-
-/**
- * A base container of prepared structured AFP objects
- */
-public abstract class AbstractGraphicsObjectContainer extends AbstractNamedAFPObject
-implements StructuredDataObject {
-
- /** list of objects contained within this container */
- protected List/*<StructuredDataObject>*/ objects
- = new java.util.ArrayList/*<StructuredDataObject>*/();
-
- /**
- * Default constructor
- */
- protected AbstractGraphicsObjectContainer() {
- }
-
- /**
- * Named constructor
- *
- * @param name the name of the container
- */
- protected AbstractGraphicsObjectContainer(String name) {
- super(name);
- }
-
- /** {@inheritDoc} */
- protected void writeContent(OutputStream os) throws IOException {
- writeObjects(objects, os);
- }
-
- /**
- * Adds a given graphics object to this container
- *
- * @param drawingOrder the graphics object
- */
- public void addObject(StructuredDataObject drawingOrder) {
- objects.add(drawingOrder);
- }
-
- /**
- * Returns the current data length
- *
- * @return the current data length of this container including
- * all enclosed objects (and their containers)
- */
- public int getDataLength() {
- int dataLen = 0;
- Iterator it = objects.iterator();
- while (it.hasNext()) {
- dataLen += ((StructuredDataObject)it.next()).getDataLength();
- }
- return dataLen;
- }
-}
+++ /dev/null
-/*
- * 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.afp.goca;
-
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.afp.AFPConstants;
-
-public abstract class AbstractGraphicsString extends AbstractGraphicsCoord {
-
- /** Up to 255 bytes of character data */
- protected static final int MAX_STR_LEN = 255;
-
- /** the string to draw */
- protected final String str;
-
- /**
- * Constructor (relative)
- *
- * @param str the text string
- */
- public AbstractGraphicsString(String str) {
- super(null);
- if (str.length() > MAX_STR_LEN) {
- str = str.substring(0, MAX_STR_LEN);
- log.warn("truncated character string, longer than " + MAX_STR_LEN + " chars");
- }
- this.str = str;
- }
-
- /**
- * Constructor (absolute)
- *
- * @param str the text string
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public AbstractGraphicsString(String str, int x, int y) {
- super(x, y);
- this.str = str;
- }
-
- /** {@inheritDoc} */
- public int getDataLength() {
- return 2 + str.length();
- }
-
- /**
- * Returns the text string as an encoded byte array
- *
- * @return the text string as an encoded byte array
- */
- protected byte[] getStringAsBytes() throws UnsupportedEncodingException {
- return str.getBytes(AFPConstants.EBCIDIC_ENCODING);
- }
-
-}
+++ /dev/null
-/*
- * 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.afp.goca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/**
- * A GOCA graphics area (container for filled shapes/objects)
- */
-public final class GraphicsArea extends AbstractGraphicsObjectContainer {
-
- 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;
- }
-
- /** {@inheritDoc} */
- public int getDataLength() {
- return 4 + super.getDataLength();
- }
-
- /** {@inheritDoc} */
- protected void writeStart(OutputStream os) throws IOException {
- byte[] data = new byte[] {
- (byte)0x68, // GBAR order code
- (byte)(RES1 + (drawBoundary ? BOUNDARY : NO_BOUNDARY))
- };
- os.write(data);
- }
-
- /** {@inheritDoc} */
- protected void writeEnd(OutputStream os) throws IOException {
- byte[] data = new byte[] {
- (byte)0x60, // GEAR order code
- 0x00, // LENGTH
- };
- os.write(data);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "GraphicsArea{drawBoundary=" + drawBoundary + "}";
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.afp.goca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The beginning of a filled region (graphics area).
+ */
+public class GraphicsAreaBegin extends AbstractGraphicsDrawingOrder {
+
+ 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;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = new byte[] {
+ getOrderCode(), // GBAR order code
+ (byte)(RES1 + (drawBoundary ? BOUNDARY : NO_BOUNDARY))
+ };
+ os.write(data);
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 2;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "GraphicsAreaBegin{drawBoundary=" + drawBoundary + "}";
+ }
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x68;
+ }
+}
--- /dev/null
+/*
+ * 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.afp.goca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The end of a filled region (graphics area).
+ */
+public class GraphicsAreaEnd extends AbstractGraphicsDrawingOrder {
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = new byte[] {
+ getOrderCode(), // GEAR order code
+ 0x00, // LENGTH
+ };
+ os.write(data);
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 2;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "GraphicsAreaEnd";
+ }
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x60;
+ }
+}
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.StructuredDataObject;
import org.apache.fop.afp.util.BinaryUtils;
/**
* A GOCA graphics segment
*/
-public final class GraphicsChainedSegment extends AbstractGraphicsObjectContainer {
+public final class GraphicsChainedSegment extends AbstractGraphicsDrawingOrderContainer {
/** The maximum segment data length */
protected static final int MAX_DATA_LEN = 8192;
- /** the current area */
- private GraphicsArea currentArea = null;
-
- /** the previous segment in the chain */
- private GraphicsChainedSegment previous = null;
-
- /** the next segment in the chain */
- private GraphicsChainedSegment next = null;
+ private byte[] predecessorNameBytes;
/**
* Main constructor
*
* @param name
* the name of this graphics segment
- * @param previous
- * the previous graphics segment in this chain
+ * @param predecessorNameBytes
+ * the name of the predecessor in this chain
*/
- public GraphicsChainedSegment(String name, GraphicsChainedSegment previous) {
+ public GraphicsChainedSegment(String name, byte[] predecessorNameBytes) {
super(name);
- previous.next = this;
- this.previous = previous;
+ this.predecessorNameBytes = predecessorNameBytes;
}
/** {@inheritDoc} */
}
/** {@inheritDoc} */
- protected void writeStart(OutputStream os) throws IOException {
- super.writeStart(os);
-
+ public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[14];
data[0] = getOrderCode(); // BEGIN_SEGMENT
data[1] = 0x0C; // Length of following parameters
data[9] = len[1];
// P/S NAME (predecessor name)
- if (previous != null) {
- nameBytes = previous.getNameBytes();
- System.arraycopy(nameBytes, 0, data, 10, NAME_LENGTH);
+ if (predecessorNameBytes != null) {
+ System.arraycopy(predecessorNameBytes, 0, data, 10, NAME_LENGTH);
}
os.write(data);
- }
-
- /** {@inheritDoc} */
- protected void writeEnd(OutputStream os) throws IOException {
- // I am the first segment in the chain so write out the rest
- if (previous == null) {
- for (GraphicsChainedSegment segment = next; segment != null; segment = segment.next) {
- segment.writeToStream(os);
- }
- } // else nothing todo
- }
- /** Begins a graphics area (start of fill) */
- protected void beginArea() {
- this.currentArea = new GraphicsArea();
- super.addObject(currentArea);
- }
-
- /** Ends a graphics area (end of fill) */
- protected void endArea() {
- this.currentArea = null;
- }
-
- /** {@inheritDoc} */
- public void addObject(StructuredDataObject drawingOrder) {
- if (currentArea != null) {
- currentArea.addObject(drawingOrder);
- } else {
- super.addObject(drawingOrder);
- }
+ writeObjects(objects, os);
}
/** {@inheritDoc} */
--- /dev/null
+/*
+ * 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.afp.goca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.afp.AFPConstants;
+
+/**
+ * A GOCA graphics string
+ */
+public class GraphicsCharacterString extends AbstractGraphicsCoord {
+
+ /** Up to 255 bytes of character data */
+ protected static final int MAX_STR_LEN = 255;
+
+ /** the string to draw */
+ protected final String str;
+
+ /**
+ * Constructor (absolute positioning)
+ *
+ * @param str the character string
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ public GraphicsCharacterString(String str, int x, int y) {
+ super(x, y);
+ this.str = truncate(str);
+ }
+
+ /**
+ * Constructor (relative positioning)
+ *
+ * @param str the character string
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+ public GraphicsCharacterString(String str) {
+ super(null);
+ this.str = truncate(str);
+ }
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ if (isRelative()) {
+ return (byte)0x83;
+ } else {
+ return (byte)0xC3;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return super.getDataLength() + str.length();
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = getData();
+ byte[] strData = getStringAsBytes();
+ System.arraycopy(strData, 0, data, 6, strData.length);
+ os.write(data);
+ }
+
+ /**
+ * Truncates the string as necessary
+ *
+ * @param str a character string
+ * @return a possibly truncated string
+ */
+ private String truncate(String str) {
+ if (str.length() > MAX_STR_LEN) {
+ str = str.substring(0, MAX_STR_LEN);
+ log.warn("truncated character string, longer than " + MAX_STR_LEN + " chars");
+ }
+ return str;
+ }
+
+ /**
+ * Returns the text string as an encoded byte array
+ *
+ * @return the text string as an encoded byte array
+ */
+ private byte[] getStringAsBytes() throws UnsupportedEncodingException {
+ return str.getBytes(AFPConstants.EBCIDIC_ENCODING);
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "GraphicsCharacterString{"
+ + (coords != null ? "x=" + coords[0] + ", y=" + coords[1] : "")
+ + "str='" + str + "'" + "}";
+ }
+}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.StructuredDataObject;
+import org.apache.fop.afp.StructuredData;
import org.apache.fop.afp.util.BinaryUtils;
import org.apache.fop.afp.util.StringUtils;
/**
* A GOCA graphics data
*/
-public final class GraphicsData extends AbstractGraphicsObjectContainer {
+public final class GraphicsData extends AbstractGraphicsDrawingOrderContainer {
- /** The maximum graphics data length */
+ /** the maximum graphics data length */
public static final int MAX_DATA_LEN = 32767;
- /** The graphics segment */
- private GraphicsChainedSegment segment = null;
-
- /** {@inheritDoc} */
- public int getDataLength() {
- return 8 + super.getDataLength();
- }
+ /** the graphics segment */
+ private GraphicsChainedSegment currentSegment = null;
/**
- * Begins a graphics area (start of fill)
+ * Main constructor
*/
- public void beginArea() {
- getSegment().beginArea();
+ public GraphicsData() {
}
- /**
- * Ends a graphics area (end of fill)
- */
- public void endArea() {
- getSegment().endArea();
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 8 + super.getDataLength();
}
/**
*
* @return a new segment name
*/
- private String createSegmentName() {
+ public String createSegmentName() {
return StringUtils.lpad(String.valueOf(
(super.objects != null ? super.objects.size() : 0) + 1),
'0', 4);
}
- /**
- * Returns the current graphics segment, creating one if one does not exist
- *
- * @return the current graphics chained segment
- */
- private GraphicsChainedSegment getSegment() {
- if (segment == null) {
- newSegment();
- }
- return this.segment;
- }
-
/**
* Creates a new graphics segment
*
* @return a newly created graphics segment
*/
public GraphicsChainedSegment newSegment() {
- String name = createSegmentName();
- if (segment == null) {
- this.segment = new GraphicsChainedSegment(name);
+ String segmentName = createSegmentName();
+ if (currentSegment == null) {
+ currentSegment = new GraphicsChainedSegment(segmentName);
} else {
- this.segment = new GraphicsChainedSegment(name, segment);
+ currentSegment.setComplete(true);
+ currentSegment = new GraphicsChainedSegment(segmentName, currentSegment.getNameBytes());
}
- super.addObject(segment);
- return segment;
+ super.addObject(currentSegment);
+ return currentSegment;
}
/** {@inheritDoc} */
- public void addObject(StructuredDataObject drawingOrder) {
- if (segment == null
- || (segment.getDataLength() + drawingOrder.getDataLength())
- >= GraphicsChainedSegment.MAX_DATA_LEN) {
+ public void addObject(StructuredData object) {
+ if (currentSegment == null
+ || (currentSegment.getDataLength() + object.getDataLength())
+ >= GraphicsChainedSegment.MAX_DATA_LEN) {
newSegment();
}
- segment.addObject(drawingOrder);
+ currentSegment.addObject(object);
+ }
+
+ /**
+ * Removes the current segment from this graphics data
+ *
+ * @return the current segment from this graphics data
+ */
+ public StructuredData removeCurrentSegment() {
+ this.currentSegment = null;
+ return super.removeLast();
}
/** {@inheritDoc} */
data[2] = len[1]; // Length byte 2
os.write(data);
- // get first segment in chain and write (including all its connected segments)
- GraphicsChainedSegment firstSegment = (GraphicsChainedSegment)objects.get(0);
- firstSegment.writeToStream(os);
+ writeObjects(objects, os);
}
/** {@inheritDoc} */
public String toString() {
return "GraphicsData";
}
+
+ /**
+ * Adds the given segment to this graphics data
+ *
+ * @param segment a graphics chained segment
+ */
+ public void addSegment(GraphicsChainedSegment segment) {
+ currentSegment = segment;
+ super.addObject(currentSegment);
+ }
}
\ No newline at end of file
*
* @param coords the x/y coordinates for this object
*/
- public GraphicsFillet(int[] coords) {
- super(coords);
+ public GraphicsFillet(int[] coords, boolean relative) {
+ super(coords, relative);
}
+ /** {@inheritDoc} */
byte getOrderCode() {
- return (byte)0xC5;
+ if (isRelative()) {
+ return (byte)0x85;
+ } else {
+ return (byte)0xC5;
+ }
}
}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.afp.goca;
-
-
-/**
- * A GOCA graphics curved tangential line to a specified set of
- * straight lines drawn from the given position or current position
- */
-public final class GraphicsFilletRelative extends AbstractGraphicsCoord {
-
- /**
- * Constructor
- *
- * @param coords the x/y coordinates for this object
- */
- public GraphicsFilletRelative(int[] coords) {
- super(coords);
- }
-
- /** {@inheritDoc} */
- byte getOrderCode() {
- return (byte)0x85;
- }
-}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractStructuredObject;
import org.apache.fop.afp.util.BinaryUtils;
/**
* A GOCA Image
*/
-public class GraphicsImage extends AbstractStructuredObject {
+public class GraphicsImage extends AbstractGraphicsDrawingOrder {
+
+ /** the maximum image data length */
+ public static final short MAX_DATA_LEN = 255;
/** x coordinate */
private final int x;
}
/** {@inheritDoc} */
- protected void writeStart(OutputStream os) throws IOException {
+ public int getDataLength() {
+ //TODO:
+ return 0;
+ }
+
+ byte getOrderCode() {
+ return (byte)0xD1;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(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);
- byte[] data = new byte[] {
- (byte) 0xD1, // GBIMG order code
+ byte[] startData = new byte[] {
+ getOrderCode(), // GBIMG order code
(byte) 0x0A, // LENGTH
xcoord[0],
xcoord[1],
h[0], // HEIGHT
h[1] //
};
- os.write(data);
- }
-
- /** the maximum image data length */
- public static final short MAX_DATA_LEN = 255;
+ os.write(startData);
- /** {@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[] endData = new byte[] {
(byte) 0x93, // GEIMG order code
0x00 // LENGTH
};
- os.write(data);
+ os.write(endData);
}
/** {@inheritDoc} */
package org.apache.fop.afp.goca;
+import java.io.IOException;
+import java.io.OutputStream;
+
/**
* A GOCA graphics straight line drawn from the
* given absolute position
* Constructor
*
* @param coords the x/y coordinates for this object
+ *
+ * @param relative is this a relative drawing order
*/
- public GraphicsLine(int[] coords) {
- super(coords);
+ public GraphicsLine(int[] coords, boolean relative) {
+ super(coords, relative);
}
/** {@inheritDoc} */
byte getOrderCode() {
- return (byte)0xC1;
+ if (isRelative()) {
+ return (byte)0x81;
+ } else {
+ return (byte)0xC1;
+ }
}
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = getData();
+ os.write(data);
+ }
}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.afp.goca;
-
-/**
- * A GOCA graphics straight line drawn from the
- * relative from the current position.
- */
-public class GraphicsLineRelative extends AbstractGraphicsCoord {
-
- /**
- * Constructor
- *
- * @param coords the x/y coordinates for this object
- */
- public GraphicsLineRelative(int[] coords) {
- super(coords);
- }
-
- /** {@inheritDoc} */
- byte getOrderCode() {
- return (byte)0x81;
- }
-
-}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
import org.apache.fop.afp.util.BinaryUtils;
/**
* Sets the current character set (font) to be used for following graphics strings
*/
-public class GraphicsSetCharacterSet extends AbstractNamedAFPObject
- implements StructuredDataObject {
+public class GraphicsSetCharacterSet extends AbstractGraphicsDrawingOrder {
/** font character set reference */
private final int fontReference;
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
- 0x38, // GSCS order code
+ getOrderCode(), // GSCS order code
BinaryUtils.convert(fontReference)[0]
};
os.write(data);
return "GraphicsSetCharacterSet(" + fontReference + ")";
}
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x38;
+ }
+
}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
-
/**
* Sets the value of the current line type attribute when stroking GOCA shapes (structured fields)
*/
-public class GraphicsSetLineType extends AbstractNamedAFPObject
-implements StructuredDataObject {
+public class GraphicsSetLineType extends AbstractGraphicsDrawingOrder {
/** the default line type */
public static final byte DEFAULT = 0x00; // normally SOLID
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
- 0x18, // GSLW order code
+ getOrderCode(), // GSLW order code
type // line type
};
os.write(data);
public String toString() {
return "GraphicsSetLineType{type=" + TYPES[type] + "}";
}
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x18;
+ }
}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
-
/**
* Sets the line width to use when stroking GOCA shapes (structured fields)
*/
-public class GraphicsSetLineWidth extends AbstractNamedAFPObject implements StructuredDataObject {
+public class GraphicsSetLineWidth extends AbstractGraphicsDrawingOrder {
/** line width multiplier */
private int multiplier = 1;
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
- 0x19, // GSLW order code
+ getOrderCode(), // GSLW order code
(byte)multiplier // MH (line-width)
};
os.write(data);
public String toString() {
return "GraphicsSetLineWidth{multiplier=" + multiplier + "}";
}
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x19;
+ }
}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-
-public class GraphicsSetMix extends AbstractNamedAFPObject {
+/**
+ * Sets the foreground mix mode.
+ */
+public class GraphicsSetMix extends AbstractGraphicsDrawingOrder {
public static final byte MODE_DEFAULT = 0x00;
public static final byte MODE_OVERPAINT = 0x02;
return "GraphicsSetMix{mode=" + mode + "}";
}
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x0C;
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 2;
+ }
+
}
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
-
/**
* Sets the pattern symbol to use when filling following GOCA structured fields
*/
-public class GraphicsSetPatternSymbol extends AbstractNamedAFPObject
-implements StructuredDataObject {
+public class GraphicsSetPatternSymbol extends AbstractGraphicsDrawingOrder {
/** dotted density 1 */
public static final byte DOTTED_DENSITY_1 = 0x01;
public static final byte BLANK = 0x40; // processed same as NO_FILL
/** the graphics pattern symbol to use */
- private final byte symbol;
+ private final byte pattern;
/**
* Main constructor
*
* @param symb the pattern symbol to use
*/
- public GraphicsSetPatternSymbol(byte symb) {
- this.symbol = symb;
+ public GraphicsSetPatternSymbol(byte pattern) {
+ this.pattern = pattern;
}
/** {@inheritDoc} */
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
- 0x28, // GSPT order code
- symbol
+ getOrderCode(), // GSPT order code
+ pattern
};
os.write(data);
}
/** {@inheritDoc} */
public String toString() {
return "GraphicsSetPatternSymbol(fill="
- + (symbol == SOLID_FILL ? true : false) + ")";
+ + (pattern == SOLID_FILL ? true : false) + ")";
+ }
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x28;
}
}
\ No newline at end of file
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.afp.modca.AbstractNamedAFPObject;
-import org.apache.fop.afp.modca.StructuredDataObject;
-
/**
* Sets the current processing color for the following GOCA structured fields
*/
-public class GraphicsSetProcessColor extends AbstractNamedAFPObject
-implements StructuredDataObject {
+public class GraphicsSetProcessColor extends AbstractGraphicsDrawingOrder {
private final Color color;
+++ /dev/null
-/*
- * 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.afp.goca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A GOCA graphics string
- */
-public class GraphicsString extends AbstractGraphicsString {
-
- /**
- * Constructor
- *
- * @param str the character string
- * @param x the x coordinate
- * @param y the y coordinate
- */
- public GraphicsString(String str, int x, int y) {
- super(str, x, y);
- }
-
- /** {@inheritDoc} */
- byte getOrderCode() {
- return (byte)0xC3;
- }
-
- /** {@inheritDoc} */
- public int getDataLength() {
- return super.getDataLength() + (coords.length * 2);
- }
-
- /** {@inheritDoc} */
- public void writeToStream(OutputStream os) throws IOException {
- byte[] data = getData();
- byte[] strData = getStringAsBytes();
- System.arraycopy(strData, 0, data, 6, strData.length);
-
- os.write(data);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "GraphicsString{x=" + coords[0] + ", y=" + coords[1] + "str='" + str + "'" + "}";
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.afp.goca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A GOCA graphics string
- */
-public class GraphicsStringRelative extends AbstractGraphicsString {
-
- /**
- * Constructor
- *
- * @param str the character string
- */
- public GraphicsStringRelative(String str) {
- super(str);
- }
-
- /** {@inheritDoc} */
- byte getOrderCode() {
- return (byte)0x83;
- }
-
- /** {@inheritDoc} */
- public void writeToStream(OutputStream os) throws IOException {
- byte[] data = getData();
- byte[] strData = getStringAsBytes();
- System.arraycopy(strData, 0, data, 2, strData.length);
- os.write(data);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "GraphicsStringRelative{str='" + str + "'" + "}";
- }
-
-}
\ No newline at end of file
*/
public class ImageCellPosition extends AbstractAFPObject {
- /**
- * Offset of image cell in X direction
- */
+ /** offset of image cell in X direction */
private int xOffset = 0;
- /**
- * Offset of image cell in Y direction
- */
+ /** offset of image cell in Y direction */
private int yOffset = 0;
- /**
- * Size of image cell in X direction
- */
+ /** size of image cell in X direction */
private final byte[] xSize = new byte[] {(byte)0xFF, (byte)0xFF};
- /**
- * Size of image cell in Y direction
- */
+ /** size of image cell in Y direction */
private final byte[] ySize = new byte[] {(byte)0xFF, (byte)0xFF};
- /**
- * Size of fill rectangle in X direction
- */
+ /** size of fill rectangle in X direction */
private final byte[] xFillSize = new byte[] {(byte)0xFF, (byte)0xFF};
- /**
- * Size of fill rectangle in Y direction
- */
+ /** size of fill rectangle in Y direction */
private final byte[] yFillSize = new byte[] {(byte)0xFF, (byte)0xFF};
/**
- * Constructor for the ImageCellPosition
+ * Main Constructor
+ *
* @param x The offset of image cell in X direction
* @param y The offset of image cell in Y direction
*/
*/
public static final byte COMPID_G3_MMR = (byte)0x82;
- /**
- * The image size parameter
- */
+ /** the image size parameter */
private ImageSizeParameter imageSizeParameter = null;
- /**
- * The image encoding
- */
+ /** the image encoding */
private byte encoding = (byte)0x03;
- /**
- * The image ide size
- */
+ /** the image ide size */
private byte size = 1;
- /**
- * The image compression
- */
+ /** the image compression */
private byte compression = (byte)0xC0;
- /**
- * The image color model
- */
+ /** the image color model */
private byte colorModel = (byte)0x01;
- /**
- * The image data
- */
+ /** the image data */
private byte[] data;
/**
- * Constructor for the image content
+ * Main Constructor
*/
public ImageContent() {
}
0x00 // length
};
final int lengthOffset = 2;
- writeChunksToStream(this.data, dataHeader, lengthOffset, MAX_DATA_LEN, os);
+ writeChunksToStream(data, dataHeader, lengthOffset, MAX_DATA_LEN, os);
}
}
*/
public class ImageInputDescriptor extends AbstractAFPObject {
- /**
- * The resolution of the raster image (default 240)
- */
+ /** the resolution of the raster image (default 240) */
private int resolution = 240;
-
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
*/
public class ImageOutputControl extends AbstractAFPObject {
- /**
- * The orientation of the image
- */
+ /** the orientation of the image */
private int orientation = 0;
/**
*/
private int yCoord = 0;
- /**
- * Map an image point to a single presentation device
- */
+ /** map an image point to a single presentation device */
private boolean singlePoint = true;
/**
import java.io.OutputStream;
import org.apache.fop.afp.modca.AbstractAFPObject;
-import org.apache.fop.afp.modca.AbstractAFPObject.Category;
-import org.apache.fop.afp.modca.AbstractAFPObject.Type;
import org.apache.fop.afp.util.BinaryUtils;
/**
*/
public class ImageRasterData extends AbstractAFPObject {
- /**
- * The image raster data
- */
+ /** the image raster data */
private final byte[] rasterData;
/**
* Constructor for the image raster data object
+ *
* @param data The raster image data
*/
public ImageRasterData(byte[] data) {
}
/**
- * Help method to write a set of AFPObjects to the AFP datastream.
+ * Writes a collection of Streamable 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.
*/
- protected void writeObjects(Collection/*<AbstractAFPObject>*/ objects, OutputStream os)
+ protected void writeObjects(Collection/*<Streamable>*/ objects, OutputStream os)
throws IOException {
if (objects != null && objects.size() > 0) {
Iterator it = objects.iterator();
}
/**
- * Reads data chunks from an inputstream
- * and then formats them with a structured header to a given outputstream
+ * Reads data chunks from an InputStream
+ * and then formats them with a structured header to a given OutputStream
*
* @param dataHeader the header data
* @param lengthOffset offset of length field in data chunk
* @param maxChunkLength the maximum chunk length
- * @param inputStream the inputstream to read from
- * @param outputStream the outputstream to write to
+ * @param inputStream the InputStream to read from
+ * @param outputStream the OutputStream to write to
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
protected static void copyChunks(byte[] dataHeader, int lengthOffset,
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceLevel;
+import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
+import org.apache.fop.afp.Startable;
/**
* Abstract base class used by the ImageObject and GraphicsObject which both
* have define an ObjectEnvironmentGroup
*/
-public abstract class AbstractDataObject extends AbstractNamedAFPObject {
+public abstract class AbstractDataObject extends AbstractNamedAFPObject implements Startable, Completable {
/** the object environment group */
protected ObjectEnvironmentGroup objectEnvironmentGroup = null;
/** the object factory */
protected final Factory factory;
+ /** the completion status of this object */
+ private boolean complete;
+
+ /** the starting status of this object */
+ private boolean started;
+
/**
* Named constructor
*
return objectEnvironmentGroup;
}
+ /** {@inheritDoc} */
+ protected void writeStart(OutputStream os) throws IOException {
+ setStarted(true);
+ }
+
/** {@inheritDoc} */
protected void writeContent(OutputStream os) throws IOException {
- super.writeContent(os); // write triplets
if (objectEnvironmentGroup != null) {
objectEnvironmentGroup.writeToStream(os);
}
}
+ /** {@inheritDoc} */
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isStarted() {
+ return this.started;
+ }
+
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isComplete() {
+ return this.complete;
+ }
}
*
* @return the name as a byte array in EBCIDIC encoding
*/
- protected byte[] getNameBytes() {
+ public byte[] getNameBytes() {
int afpNameLen = getNameLength();
int nameLen = name.length();
if (nameLen < afpNameLen) {
* @return the name of this object
*/
public String getName() {
- return name;
+ return this.name;
+ }
+
+ /**
+ * Sets the name of this object
+ *
+ * @param name the object name
+ */
+ public void setName(String name) {
+ this.name = name;
}
/** {@inheritDoc} */
import org.apache.fop.afp.AFPLineDataInfo;
import org.apache.fop.afp.AFPTextDataInfo;
+import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.fonts.AFPFont;
* in page state.
*
*/
-public abstract class AbstractPageObject extends AbstractNamedAFPObject {
+public abstract class AbstractPageObject extends AbstractNamedAFPObject implements Completable {
/** The active environment group for the page */
protected ActiveEnvironmentGroup activeEnvironmentGroup = null;
if (currentPresentationTextObject != null) {
currentPresentationTextObject.endControlSequence();
}
- complete = true;
+ setComplete(true);
}
/**
return activeEnvironmentGroup;
}
- /**
- * Returns an indication if the page is complete
- *
- * @return whether this page is complete
- */
- public boolean isComplete() {
- return complete;
- }
-
/**
* Returns the height of the page
*
public void addObject(Object obj) {
objects.add(obj);
}
+
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isComplete() {
+ return this.complete;
+ }
}
import java.util.Collection;
import java.util.Iterator;
+import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
import org.apache.fop.afp.Streamable;
*
* @return the resource group in this resource group container
*/
- protected ResourceGroup getResourceGroup() {
+ public ResourceGroup getResourceGroup() {
if (resourceGroup == null) {
resourceGroup = factory.createResourceGroup();
}
* @return true if this object can be written
*/
protected boolean canWrite(AbstractAFPObject obj) {
- return obj instanceof AbstractPageObject && ((AbstractPageObject)obj).isComplete();
+ return obj instanceof AbstractPageObject && ((Completable)obj).isComplete();
}
}
import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
+/**
+ * A MODCA structured object base class providing support for Triplets
+ */
public class AbstractTripletStructuredObject extends AbstractStructuredObject {
/** list of object triplets */
+++ /dev/null
-/*
- * 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.afp.modca;
-
-import java.awt.Color;
-import java.awt.Point;
-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.afp.AFPLineDataInfo;
-import org.apache.fop.afp.AFPPaintingState;
-import org.apache.fop.afp.AFPResourceLevel;
-import org.apache.fop.afp.AFPTextDataInfo;
-import org.apache.fop.afp.Factory;
-import org.apache.fop.afp.fonts.AFPFont;
-import org.apache.fop.afp.fonts.AFPFontAttributes;
-import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
-
-/**
- * A data stream is a continuous ordered stream of data elements and objects
- * conforming to a given format. Application programs can generate data streams
- * destined for a presentation service, archive library, presentation device or
- * another application program. The strategic presentation data stream
- * architectures used is Mixed Object Document Content Architecture (MO:DCA).
- *
- * The MO:DCA architecture defines the data stream used by applications to
- * describe documents and object envelopes for interchange with other
- * applications and application services. Documents defined in the MO:DCA format
- * may be archived in a database, then later retrieved, viewed, annotated and
- * printed in local or distributed systems environments. Presentation fidelity
- * is accommodated by including resource objects in the documents that reference
- * them.
- */
-public class DataStream {
-
- /** Static logging instance */
- protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp.modca");
-
- /** Boolean completion indicator */
- private boolean complete = false;
-
- /** The AFP document object */
- private Document document = null;
-
- /** The current page group object */
- private PageGroup currentPageGroup = null;
-
- /** The current page object */
- private PageObject currentPageObject = null;
-
- /** The current overlay object */
- private Overlay currentOverlay = null;
-
- /** The current page */
- private AbstractPageObject currentPage = null;
-
- /** The 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 final Factory factory;
-
- private OutputStream outputStream;
-
- /** the afp painting state */
- private final AFPPaintingState state;
-
- /**
- * Default constructor for the AFPDocumentStream.
- *
- * @param factory the resource factory
- * @param state the AFP painting state
- * @param outputStream the outputstream to write to
- */
- public DataStream(Factory factory, AFPPaintingState state, OutputStream outputStream) {
- this.state = state;
- 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() {
- return this.document;
- }
-
- /**
- * Returns the current page
- *
- * @return the current page
- */
- public AbstractPageObject getCurrentPage() {
- return this.currentPage;
- }
-
- /**
- * The document is started by invoking this method which creates an instance
- * of the AFP Document object.
- *
- * @param name
- * the name of this document.
- */
- public void setDocumentName(String name) {
- if (name != null) {
- getDocument().setFullyQualifiedName(
- FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
- FullyQualifiedNameTriplet.FORMAT_CHARSTR, name);
- }
- }
-
- /** {@inheritDoc} */
- public void endDocument() throws IOException {
- if (complete) {
- String msg = "Invalid state - document already ended.";
- log.warn("endDocument():: " + msg);
- throw new IllegalStateException(msg);
- }
-
- if (currentPageObject != null) {
- // End the current page if necessary
- endPage();
- }
-
- if (currentPageGroup != null) {
- // End the current page group if necessary
- endPageGroup();
- }
-
- // Write out document
- if (document != null) {
- document.endDocument();
- document.writeToStream(this.outputStream);
- }
-
- this.outputStream.flush();
-
- this.complete = true;
-
- this.document = null;
-
- this.outputStream = null;
- }
-
- /**
- * Start a new page. When processing has finished on the current page, the
- * {@link #endPage()}method must be invoked to mark the page ending.
- *
- * @param pageWidth
- * the width of the page
- * @param pageHeight
- * the height of the page
- * @param pageRotation
- * the rotation of the page
- * @param pageWidthRes
- * the width resolution of the page
- * @param pageHeightRes
- * the height resolution of the page
- */
- public void startPage(int pageWidth, int pageHeight, int pageRotation,
- int pageWidthRes, int pageHeightRes) {
- currentPageObject = factory.createPage(pageWidth, pageHeight,
- pageRotation, pageWidthRes, pageHeightRes);
- currentPage = currentPageObject;
- currentOverlay = null;
- }
-
- /**
- * Start a new overlay. When processing has finished on the current overlay,
- * the {@link #endOverlay()}method must be invoked to mark the overlay
- * ending.
- *
- * @param x
- * the x position of the overlay on the page
- * @param y
- * the y position of the overlay on the page
- * @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
- */
- public void startOverlay(int x, int y, int width, int height, int widthRes,
- int heightRes, int overlayRotation) {
- this.currentOverlay = factory.createOverlay(
- width, height, widthRes, heightRes, overlayRotation);
-
- String overlayName = currentOverlay.getName();
- currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
- currentPage = currentOverlay;
- }
-
- /**
- * 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() throws IOException {
- if (currentOverlay != null) {
- currentOverlay.endPage();
- currentOverlay = null;
- currentPage = currentPageObject;
- }
- }
-
- /**
- * Helper method to save the current page.
- *
- * @return current page object that was saved
- */
- public PageObject savePage() {
- PageObject pageObject = currentPageObject;
- if (currentPageGroup != null) {
- currentPageGroup.addPage(currentPageObject);
- } else {
- document.addPage(currentPageObject);
- }
- currentPageObject = null;
- currentPage = null;
- return pageObject;
- }
-
- /**
- * Helper method to restore the current page.
- *
- * @param pageObject
- * page object
- */
- public void restorePage(PageObject pageObject) {
- currentPageObject = pageObject;
- currentPage = pageObject;
- }
-
- /**
- * Helper method to mark the end of the current page.
- *
- * @throws IOException thrown if an I/O exception of some sort has occurred
- */
- 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;
- }
- }
-
- /**
- * Creates the given page fonts in the current page
- *
- * @param pageFonts
- * a collection of AFP font attributes
- */
- public void addFontsToCurrentPage(Map pageFonts) {
- Iterator iter = pageFonts.values().iterator();
- while (iter.hasNext()) {
- AFPFontAttributes afpFontAttributes = (AFPFontAttributes) iter
- .next();
- createFont(afpFontAttributes.getFontReference(), afpFontAttributes
- .getFont(), afpFontAttributes.getPointSize());
- }
- }
-
- /**
- * Helper method to create a map coded font object on the current page, this
- * method delegates the construction of the map coded font object to the
- * active environment group on the current page.
- *
- * @param fontReference
- * the font number used as the resource identifier
- * @param font
- * the font
- * @param size
- * the point size of the font
- */
- public void createFont(int fontReference, AFPFont font, int size) {
- currentPage.createFont(fontReference, font, size);
- }
-
- /**
- * Returns a point on the current page
- *
- * @param x the X-coordinate
- * @param y the Y-coordinate
- * @return a point on the current page
- */
- private Point getPoint(int x, int y) {
- Point p = new Point();
- int rotation = state.getRotation();
- switch (rotation) {
- case 90:
- p.x = y;
- p.y = currentPage.getWidth() - x;
- break;
- case 180:
- p.x = currentPage.getWidth() - x;
- p.y = currentPage.getHeight() - y;
- break;
- case 270:
- p.x = currentPage.getHeight() - y;
- p.y = x;
- break;
- default:
- p.x = x;
- p.y = y;
- break;
- }
- return p;
- }
-
- /**
- * Helper method to create text on the current page, this method delegates
- * to the current presentation text object in order to construct the text.
- *
- * @param textDataInfo
- * the afp text data
- */
- public void createText(AFPTextDataInfo textDataInfo) {
- int rotation = state.getRotation();
- if (rotation != 0) {
- textDataInfo.setRotation(rotation);
- Point p = getPoint(textDataInfo.getX(), textDataInfo.getY());
- textDataInfo.setX(p.x);
- textDataInfo.setY(p.y);
- }
- currentPage.createText(textDataInfo);
- }
-
- /**
- * Method to create a line on the current page.
- *
- * @param lineDataInfo the line data information.
- */
- public void createLine(AFPLineDataInfo lineDataInfo) {
- currentPage.createLine(lineDataInfo);
- }
-
- /**
- * This method will create shading on the page using the specified
- * coordinates (the shading contrast is controlled via the red, green, blue
- * parameters, by converting this to grey scale).
- *
- * @param x
- * the x coordinate of the shading
- * @param y
- * the y coordinate of the shading
- * @param w
- * the width of the shaded area
- * @param h
- * the height of the shaded area
- * @param col
- * the shading color
- */
- public void createShading(int x, int y, int w, int h, Color col) {
- currentPageObject.createShading(x, y, w, h, col.getRed(), col.getGreen(), col.getBlue());
- }
-
- /**
- * Helper method which allows creation of the MPO object, via the AEG. And
- * the IPO via the Page. (See actual object for descriptions.)
- *
- * @param name
- * the name of the static overlay
- */
- public void createIncludePageOverlay(String name) {
- currentPageObject.createIncludePageOverlay(name, 0, 0, state.getRotation());
- currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
- }
-
- /**
- * Helper method which allows creation of the IMM object.
- *
- * @param name
- * the name of the medium map
- */
- public void createInvokeMediumMap(String name) {
- currentPageGroup.createInvokeMediumMap(name);
- }
-
- /**
- * Creates an IncludePageSegment on the current page.
- *
- * @param name
- * the name of the include page segment
- * @param x
- * the x coordinate for the overlay
- * @param y
- * the y coordinate for the overlay
- */
- public void createIncludePageSegment(String name, int x, int y) {
- int xOrigin;
- int yOrigin;
- int orientation = state.getRotation();
- switch (orientation) {
- case 90:
- xOrigin = currentPage.getWidth() - y;
- yOrigin = x;
- break;
- case 180:
- xOrigin = currentPage.getWidth() - x;
- yOrigin = currentPage.getHeight() - y;
- break;
- case 270:
- xOrigin = y;
- yOrigin = currentPage.getHeight() - x;
- break;
- default:
- xOrigin = x;
- yOrigin = y;
- break;
- }
- currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
- }
-
- /**
- * Creates a TagLogicalElement on the current page.
- *
- * @param attributes
- * the array of key value pairs.
- */
- public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
- for (int i = 0; i < attributes.length; i++) {
- String name = attributes[i].getKey();
- String value = attributes[i].getValue();
- currentPage.createTagLogicalElement(name, value);
- }
- }
-
- /**
- * Creates a TagLogicalElement on the current page group.
- *
- * @param attributes
- * the array of key value pairs.
- */
- public void createPageGroupTagLogicalElement(TagLogicalElementBean[] attributes) {
- for (int i = 0; i < attributes.length; i++) {
- String name = attributes[i].getKey();
- String value = attributes[i].getValue();
- currentPageGroup.createTagLogicalElement(name, value);
- }
- }
-
- /**
- * Creates a TagLogicalElement on the current page or page group
- *
- * @param name
- * The tag name
- * @param value
- * The tag value
- */
- public void createTagLogicalElement(String name, String value) {
- if (currentPageGroup != null) {
- currentPageGroup.createTagLogicalElement(name, value);
- } else {
- currentPage.createTagLogicalElement(name, value);
- }
- }
-
- /**
- * Creates a NoOperation item
- *
- * @param content
- * byte data
- */
- public void createNoOperation(String content) {
- currentPage.createNoOperation(content);
- }
-
- /**
- * Returns the current page group
- *
- * @return the current page group
- */
- 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() 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() throws IOException {
- if (currentPageGroup != null) {
- currentPageGroup.endPageGroup();
- document.addPageGroup(currentPageGroup);
- document.writeToStream(outputStream);
- currentPageGroup = null;
- }
- }
-
- /**
- * 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;
- }
-
- /**
- * 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.isDocument()) {
- resourceGroup = document.getResourceGroup();
- } else if (level.isPageGroup()) {
- resourceGroup = currentPageGroup.getResourceGroup();
- } else if (level.isPage()) {
- resourceGroup = currentPageObject.getResourceGroup();
- }
- return resourceGroup;
- }
-
-}
complete = true;
}
- /**
- * Returns an indication if the page group is complete
- *
- * @return whether or not this page group is complete
- */
+ /** {@inheritDoc} */
public boolean isComplete() {
return complete;
}
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Iterator;
import java.util.List;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.Completable;
import org.apache.fop.afp.Factory;
+import org.apache.fop.afp.StructuredData;
+import org.apache.fop.afp.goca.GraphicsAreaBegin;
+import org.apache.fop.afp.goca.GraphicsAreaEnd;
import org.apache.fop.afp.goca.GraphicsBox;
+import org.apache.fop.afp.goca.GraphicsChainedSegment;
+import org.apache.fop.afp.goca.GraphicsCharacterString;
import org.apache.fop.afp.goca.GraphicsData;
import org.apache.fop.afp.goca.GraphicsFillet;
-import org.apache.fop.afp.goca.GraphicsFilletRelative;
import org.apache.fop.afp.goca.GraphicsFullArc;
+import org.apache.fop.afp.goca.GraphicsImage;
import org.apache.fop.afp.goca.GraphicsLine;
-import org.apache.fop.afp.goca.GraphicsLineRelative;
import org.apache.fop.afp.goca.GraphicsSetArcParameters;
import org.apache.fop.afp.goca.GraphicsSetCharacterSet;
import org.apache.fop.afp.goca.GraphicsSetCurrentPosition;
import org.apache.fop.afp.goca.GraphicsSetLineWidth;
import org.apache.fop.afp.goca.GraphicsSetPatternSymbol;
import org.apache.fop.afp.goca.GraphicsSetProcessColor;
-import org.apache.fop.afp.goca.GraphicsString;
/**
* Top-level GOCA graphics object.
public class GraphicsObject extends AbstractDataObject {
/** The graphics data */
- private GraphicsData data = null;
+ private GraphicsData currentData = null;
/** list of objects contained within this container */
protected List/*<GraphicsDrawingOrder>*/ objects
= new java.util.ArrayList/*<GraphicsDrawingOrder>*/();
+ /** the current color */
+ private Color currentColor;
+
+ /** the current line type */
+ private byte currentLineType;
+
+ /** the current line width */
+ private int currentLineWidth;
+
+ /** the current fill pattern */
+ private byte currentPatternSymbol;
+
+ /** the current character set */
+ private int currentCharacterSet;
+
/**
* Default constructor
*
}
/** {@inheritDoc} */
- public void addObject(StructuredDataObject drawingOrder) {
- if (data == null
- || (data.getDataLength() + drawingOrder.getDataLength())
- >= GraphicsData.MAX_DATA_LEN) {
+ public void addObject(StructuredData object) {
+ if (currentData == null) {
newData();
+ } else if (currentData.getDataLength() + object.getDataLength()
+ >= GraphicsData.MAX_DATA_LEN) {
+ // graphics data full so transfer current incomplete segment to new data
+ GraphicsChainedSegment currentSegment
+ = (GraphicsChainedSegment)currentData.removeCurrentSegment();
+ currentSegment.setName(newData().createSegmentName());
+ currentData.addSegment(currentSegment);
}
- data.addObject(drawingOrder);
+ currentData.addObject(object);
}
/**
* @return the current graphics data
*/
private GraphicsData getData() {
- if (this.data == null) {
+ if (this.currentData == null) {
return newData();
}
- return this.data;
+ return this.currentData;
}
/**
* @return a newly created graphics data
*/
private GraphicsData newData() {
- this.data = factory.createGraphicsData();
- objects.add(data);
- return data;
+ if (currentData != null) {
+ currentData.setComplete(true);
+ }
+ this.currentData = factory.createGraphicsData();
+ objects.add(currentData);
+ return currentData;
}
/**
* @param color the active color to use
*/
public void setColor(Color color) {
- addObject(new GraphicsSetProcessColor(color));
+ if (!color.equals(currentColor)) {
+ this.currentColor = color;
+ addObject(new GraphicsSetProcessColor(color));
+ }
}
/**
/**
* Sets the line width
*
- * @param multiplier the line width multiplier
+ * @param lineWidth the line width multiplier
*/
- public void setLineWidth(int multiplier) {
- GraphicsSetLineWidth graphicsSetLineWidth = new GraphicsSetLineWidth(multiplier);
- addObject(graphicsSetLineWidth);
+ public void setLineWidth(int lineWidth) {
+ if (lineWidth != currentLineWidth) {
+ currentLineWidth = lineWidth;
+ addObject(new GraphicsSetLineWidth(lineWidth));
+ }
}
/**
* Sets the line type
*
- * @param type the line type
+ * @param lineType the line type
*/
- public void setLineType(byte type) {
- GraphicsSetLineType graphicsSetLineType = new GraphicsSetLineType(type);
- addObject(graphicsSetLineType);
+ public void setLineType(byte lineType) {
+ if (lineType != currentLineType) {
+ currentLineType = lineType;
+ addObject(new GraphicsSetLineType(lineType));
+ }
}
/**
- * Sets whether to fill the next shape
+ * Sets whether the following shape is to be filled
*
- * @param fill whether to fill the next shape
+ * @param fill true if the following shape is to be filled
*/
public void setFill(boolean fill) {
- GraphicsSetPatternSymbol graphicsSetPattern = new GraphicsSetPatternSymbol(
- fill ? GraphicsSetPatternSymbol.SOLID_FILL
- : GraphicsSetPatternSymbol.NO_FILL
- );
- addObject(graphicsSetPattern);
+ setPatternSymbol(fill ?
+ GraphicsSetPatternSymbol.SOLID_FILL :
+ GraphicsSetPatternSymbol.NO_FILL);
+ }
+
+ /**
+ * Sets the fill pattern of the next shape
+ *
+ * @param the fill pattern of the next shape
+ */
+ public void setPatternSymbol(byte patternSymbol) {
+ if (currentPatternSymbol != patternSymbol) {
+ currentPatternSymbol = patternSymbol;
+ addObject(new GraphicsSetPatternSymbol(patternSymbol));
+ }
}
/**
* Sets the character set to use
*
- * @param fontReference the character set (font) reference
+ * @param characterSet the character set (font) reference
*/
- public void setCharacterSet(int fontReference) {
- addObject(new GraphicsSetCharacterSet(fontReference));
+ public void setCharacterSet(int characterSet) {
+ if (currentCharacterSet != characterSet) {
+ currentCharacterSet = characterSet;
+ addObject(new GraphicsSetCharacterSet(characterSet));
+ }
}
/**
* @param relative relative true for a line at current position (relative to)
*/
public void addLine(int[] coords, boolean relative) {
- if (relative) {
- addObject(new GraphicsLineRelative(coords));
- } else {
- addObject(new GraphicsLine(coords));
- }
+ addObject(new GraphicsLine(coords, relative));
}
/**
* Adds a fillet (curve) at the given coordinates
*
* @param coords the x/y coordinates
- * @param relative relative true for a fillet at current position (relative to)
+ * @param relative relative true for a fillet (curve) at current position (relative to)
*/
public void addFillet(int[] coords, boolean relative) {
- if (relative) {
- addObject(new GraphicsFilletRelative(coords));
- } else {
- addObject(new GraphicsFillet(coords));
- }
+ addObject(new GraphicsFillet(coords, relative));
}
/**
}
/**
- * Adds an arc
+ * Adds a full arc
*
* @param x the x coordinate
* @param y the y coordinate
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 GraphicsImage(x, y, width, height, imgData));
-// }
+ /**
+ * 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 y the y coordinate
*/
public void addString(String str, int x, int y) {
- addObject(new GraphicsString(str, x, y));
+ addObject(new GraphicsCharacterString(str, x, y));
}
/**
* Begins a graphics area (start of fill)
*/
public void beginArea() {
- if (data == null) {
- newData();
- }
- data.beginArea();
+ addObject(new GraphicsAreaBegin());
}
/**
* Ends a graphics area (end of fill)
*/
public void endArea() {
- if (data != null) {
- data.endArea();
- }
+ addObject(new GraphicsAreaEnd());
}
/** {@inheritDoc} */
getData().newSegment();
}
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ Iterator it = objects.iterator();
+ while (it.hasNext()) {
+ Completable completedObject = (Completable)it.next();
+ completedObject.setComplete(true);
+ }
+ super.setComplete(complete);
+ }
+
/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
+ super.writeStart(os);
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);
+ writeObjects(objects, os);
}
/** {@inheritDoc} */
*/
public class MapCodedFont extends AbstractStructuredObject {
- /**
- * The collection of map coded fonts (maximum of 254)
- */
+ /** the collection of map coded fonts (maximum of 254) */
private final List/*<FontDefinition>*/ fontList
= new java.util.ArrayList/*<FontDefinition>*/();
/**
- * Constructor for the MapCodedFont
+ * Main constructor
*/
public MapCodedFont() {
}
public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject {
/** the PresentationEnvironmentControl for the object environment group */
- private PresentationEnvironmentControl presentationEnvironmentControl = null;
+ private PresentationEnvironmentControl presentationEnvironmentControl;
/** the ObjectAreaDescriptor for the object environment group */
- private ObjectAreaDescriptor objectAreaDescriptor = null;
+ private ObjectAreaDescriptor objectAreaDescriptor;
/** the ObjectAreaPosition for the object environment group */
- private ObjectAreaPosition objectAreaPosition = null;
+ private ObjectAreaPosition objectAreaPosition;
/** the DataDescriptor for the object environment group */
private AbstractDescriptor dataDescriptor;
data[2] = len[1];
os.write(data);
+
+ writeTriplets(os);
}
/** {@inheritDoc} */
/**
* Method to mark the end of the page group.
*/
- protected void endPageGroup() {
+ public void endPageGroup() {
complete = true;
}
* 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.
import java.io.OutputStream;
import java.util.List;
+import org.apache.fop.afp.Completable;
+
/**
* A Resource Environment Group contains a set of resources for a document
* or for a group of pages in a document.
*/
-public class ResourceEnvironmentGroup extends AbstractEnvironmentGroup {
- /**
- * Default name for the resource group
- */
+public class ResourceEnvironmentGroup extends AbstractEnvironmentGroup implements Completable {
+
+ /** default name for the resource group */
private static final String DEFAULT_NAME = "REG00001";
- /**
- * The maps data resources contained in this resource environment group
- */
+ /** the maps data resources contained in this resource environment group */
private List/*<MapDataResource>*/ mapDataResources = null;
-
- /**
- * The maps page overlays contained in this resource environment group
- */
+
+ /** the maps page overlays contained in this resource environment group */
private List mapPageOverlays = null;
-
- /**
- * The pre-process presentation objects contained in this resource environment group
- */
+
+ /** the pre-process presentation objects contained in this resource environment group */
private List/*<PreprocessPresentationObject>*/ preProcessPresentationObjects = null;
- /**
- * The resource environment group state
- */
+ /** the resource environment group state */
private boolean complete = false;
/**
// createOverlay(obj.get);
// getPreprocessPresentationObjects().add(new PreprocessPresentationObject(obj));
// }
-
- /**
- * Returns an indication if the resource environment group is complete
- *
- * @return whether or not this resource environment group is complete or not
- */
- public boolean isComplete() {
- return complete;
- }
-
+
/** {@inheritDoc} */
protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
writeObjects(preProcessPresentationObjects, os);
}
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isComplete() {
+ return complete;
+ }
+
}
import java.io.IOException;
import java.io.OutputStream;
+import org.apache.fop.afp.Completable;
+
/**
* A print-file resource group
*/
-public class StreamedResourceGroup extends ResourceGroup {
+public class StreamedResourceGroup extends ResourceGroup implements Completable {
/** the outputstream to write to */
private final OutputStream 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
*
public OutputStream getOutputStream() {
return this.os;
}
+
+ /** {@inheritDoc} */
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isComplete() {
+ return this.complete;
+ }
+
}
\ No newline at end of file
+++ /dev/null
-/*
- * 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.afp.modca;
-
-/**
- * An AFP object which is able to know its own data length before writeToStream()
- */
-public interface StructuredDataObject {
-
- /**
- * Returns the data length of this structured field
- *
- * @return the data length of this structured field
- */
- int getDataLength();
-}
\ No newline at end of file
package org.apache.fop.afp.modca.triplets;
import org.apache.fop.afp.Streamable;
-import org.apache.fop.afp.modca.StructuredDataObject;
+import org.apache.fop.afp.StructuredData;
/**
* A simple implementation of a MOD:CA triplet
*/
-public abstract class AbstractTriplet implements Streamable, StructuredDataObject {
+public abstract class AbstractTriplet implements Streamable, StructuredData {
public static final byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01;
/** Triplet identifiers */
import java.io.IOException;
import java.io.OutputStream;
+/**
+ * Associates an ObjectAreaPosition with and ObjectAreaDescriptor structured field
+ */
public class DescriptorPositionTriplet extends AbstractTriplet {
private final byte oapId;
import java.io.IOException;
import java.io.OutputStream;
-/** resource object type triplet */
+/** A Resource Object Type Triplet */
public class ResourceObjectTypeTriplet extends AbstractTriplet {
private static final byte RESOURCE_OBJECT = 0x21;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+/**
+ * An AFP specific implementation of a Batik BridgeContext
+ */
public class AFPBridgeContext extends AbstractFOPBridgeContext {
private final AFPGraphics2D g2d;
import org.apache.fop.svg.AbstractFOPImageElementBridge;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
+/**
+ * An AFP specific implementation of a Batik SVGImageElementBridge
+ */
public class AFPImageElementBridge extends AbstractFOPImageElementBridge {
private final ImageFlavor[] supportedFlavors = new ImageFlavor[]
--- /dev/null
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.modca.svg Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP specific Batik bridges.</P>
+</BODY>
+</HTML>
\ No newline at end of file
--- /dev/null
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.modca.triplets Package</TITLE>
+<BODY>
+<P>Contains a collection of useful AFP utility classes.</P>
+</BODY>
+</HTML>
\ No newline at end of file
* This call should be used when the q operator is used
* so that the state is known when popped.
*/
- public void push() {
+ public void save() {
AbstractData data = getData();
AbstractData copy = (AbstractData)data.clone();
data.clearTransform();
final boolean textAsShapes = false;
AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes);
- paintingState.push();
+ paintingState.save();
//Fallback solution: Paint to a BufferedImage
if (afpInfo.paintAsBitmap()) {
resourceManager.createObject(graphicsObjectInfo);
}
- paintingState.pop();
+ paintingState.restore();
}
/** {@inheritDoc} */
/**
* Sets the AFP state
*
- * @param state the AFP state
+ * @param paintingState the AFP state
*/
- public void setPaintingState(AFPPaintingState state) {
- this.paintingState = state;
+ public void setPaintingState(AFPPaintingState paintingState) {
+ this.paintingState = paintingState;
}
/**
import org.apache.fop.afp.AFPResourceManager;
import org.apache.fop.afp.AFPTextDataInfo;
import org.apache.fop.afp.AFPUnitConverter;
-import org.apache.fop.afp.BorderPaintInfo;
-import org.apache.fop.afp.RectanglePaintInfo;
+import org.apache.fop.afp.BorderPaintingInfo;
+import org.apache.fop.afp.DataStream;
+import org.apache.fop.afp.RectanglePaintingInfo;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontAttributes;
import org.apache.fop.afp.fonts.AFPFontCollection;
import org.apache.fop.afp.fonts.AFPPageFonts;
-import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.afp.modca.PageObject;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
*/
public AFPRenderer() {
super();
+ this.imageHandlerRegistry = new AFPImageHandlerRegistry();
this.resourceManager = new AFPResourceManager();
this.paintingState = new AFPPaintingState();
- this.imageHandlerRegistry = new AFPImageHandlerRegistry();
this.unitConv = paintingState.getUnitConverter();
}
/** {@inheritDoc} */
public void drawBorderLine(float x1, float y1, float x2, float y2,
boolean horz, boolean startOrBefore, int style, Color col) {
- BorderPaintInfo borderPaintInfo = new BorderPaintInfo(x1, y1, x2, y2, horz, style, col);
+ BorderPaintingInfo borderPaintInfo = new BorderPaintingInfo(x1, y1, x2, y2, horz, style, col);
borderPainter.paint(borderPaintInfo);
}
/** {@inheritDoc} */
public void fillRect(float x, float y, float width, float height) {
- RectanglePaintInfo rectanglePaintInfo = new RectanglePaintInfo(x, y, width, height);
+ RectanglePaintingInfo rectanglePaintInfo = new RectanglePaintingInfo(x, y, width, height);
rectanglePainter.paint(rectanglePaintInfo);
}
/** {@inheritDoc} */
public void restoreStateStackAfterBreakOut(List breakOutList) {
log.debug("Block.FIXED --> restoring context after break-out");
- paintingState.pushAll(breakOutList);
+ paintingState.saveAll(breakOutList);
}
/** {@inheritDoc} */
protected List breakOutOfStateStack() {
log.debug("Block.FIXED --> break out");
- return paintingState.popAll();
+ return paintingState.restoreAll();
}
/** {@inheritDoc} */
public void saveGraphicsState() {
- paintingState.push();
+ paintingState.save();
}
/** {@inheritDoc} */
public void restoreGraphicsState() {
- paintingState.pop();
+ paintingState.restore();
}
/** {@inheritDoc} */
int height = afpInfo.getHeight();
int resolution = afpInfo.getResolution();
- paintingState.push(); // save
+ paintingState.save(); // save
AFPObjectAreaInfo objectAreaInfo
= createObjectAreaInfo(paintingState, x, y, width, height, resolution);
AFPResourceManager resourceManager = afpInfo.getResourceManager();
resourceManager.createObject(graphicsObjectInfo);
- paintingState.pop(); // resume
+ paintingState.restore(); // resume
}
private AFPObjectAreaInfo createObjectAreaInfo(AFPPaintingState paintingState,
/** {@inheritDoc} */
protected void saveGraphicsState() {
endTextObject();
- paintingState.push();
+ paintingState.save();
currentStream.add("q\n");
}
endTextObject();
currentStream.add("Q\n");
if (popState) {
- paintingState.pop();
+ paintingState.restore();
}
}
AbstractPaintingState.AbstractData data;
while (true) {
data = paintingState.getData();
- if (paintingState.pop() == null) {
+ if (paintingState.restore() == null) {
break;
}
if (breakOutList.size() == 0) {
public void renderLeader(Leader area) {
renderInlineAreaBackAndBorders(area);
- paintingState.push();
+ paintingState.save();
saveGraphicsState();
int style = area.getRuleStyle();
float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
}
restoreGraphicsState();
- paintingState.pop();
+ paintingState.restore();
beginTextObject();
super.renderLeader(area);
}
pdfInfo.currentStream.add("%SVG start\n");
//Save state and update coordinate system for the SVG image
- pdfInfo.pdfPaintingState.push();
+ pdfInfo.pdfPaintingState.save();
pdfInfo.pdfPaintingState.concatenate(imageTransform);
//Now that we have the complete transformation matrix for the image, we can update the
context.getUserAgent().getEventBroadcaster());
eventProducer.svgRenderingError(this, e, getDocumentURI(doc));
}
- pdfInfo.pdfPaintingState.pop();
+ pdfInfo.pdfPaintingState.restore();
renderer.restoreGraphicsState();
pdfInfo.currentStream.add("%SVG end\n");
}
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+/**
+ * A FOP base implementation of a Batik BridgeContext.
+ */
public abstract class AbstractFOPBridgeContext extends BridgeContext {
/** The font list. */
if (newClip || newTransform) {
currentStream.write("q\n");
- paintingState.push();
+ paintingState.save();
if (newTransform) {
concatMatrix(tranvals);
}
if (newClip || newTransform) {
currentStream.write("Q\n");
- paintingState.pop();
+ paintingState.restore();
}
return;
}
doDrawing(false, true, false);
if (newClip || newTransform) {
currentStream.write("Q\n");
- paintingState.pop();
+ paintingState.restore();
}
}
if (newClip || newTransform) {
currentStream.write("q\n");
- paintingState.push();
+ paintingState.save();
if (newTransform) {
concatMatrix(tranvals);
}
if (newClip || newTransform) {
currentStream.write("Q\n");
- paintingState.pop();
+ paintingState.restore();
}
return;
}
iter.getWindingRule() == PathIterator.WIND_EVEN_ODD);
if (newClip || newTransform) {
currentStream.write("Q\n");
- paintingState.pop();
+ paintingState.restore();
}
}
import java.util.List;
import java.util.Stack;
-
/**
- * A base class which holds information about the current rendering state.
+ * A base class which holds information about the current painting state.
*/
public abstract class AbstractPaintingState implements Cloneable, Serializable {
/**
- * Push the current painting state onto the stack.
+ * Save the current painting state.
+ * This pushes the current painting state onto the stack.
* This call should be used when the Q operator is used
* so that the state is known when popped.
*/
- public void push() {
+ public void save() {
AbstractData copy = (AbstractData)getData().clone();
stateStack.push(copy);
}
/**
- * Pop the painting 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.
+ * Restore the current painting state.
+ * This pops the painting state from the stack and sets current values to popped state.
*
* @return the restored state, null if the stack is empty
*/
- public AbstractData pop() {
+ public AbstractData restore() {
if (!stateStack.isEmpty()) {
setData((AbstractData)stateStack.pop());
return this.data;
}
/**
- * Pushes all painting state data in the given list to the stack
+ * Save all painting state data.
+ * This pushes all painting state data in the given list to the stack
*
* @param dataList a state data list
*/
- public void pushAll(List/*<AbstractData>*/ dataList) {
+ public void saveAll(List/*<AbstractData>*/ dataList) {
Iterator it = dataList.iterator();
while (it.hasNext()) {
// save current data on stack
- push();
+ save();
setData((AbstractData)it.next());
}
}
/**
- * Pops all painting state data from the stack
+ * Restore all painting state data.
+ * This pops all painting state data from the stack
*
* @return a list of state data popped from the stack
*/
- public List/*<AbstractData>*/ popAll() {
+ public List/*<AbstractData>*/ restoreAll() {
List/*<AbstractData>*/ dataList = new java.util.ArrayList/*<AbstractData>*/();
AbstractData data;
while (true) {
data = getData();
- if (pop() == null) {
+ if (restore() == null) {
break;
}
// insert because of stack-popping