aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
authorAdrian Cumiskey <acumiskey@apache.org>2008-03-27 16:16:30 +0000
committerAdrian Cumiskey <acumiskey@apache.org>2008-03-27 16:16:30 +0000
commitf466690aaeed2dc93360d5f5f14fede90f2f5ad2 (patch)
tree33dc1c9a235eaf887ad80aaafa9c3990a87111ea /src/java/org/apache/fop
parent1105f2129784f6d85485ad222bdbc835473ee7ca (diff)
downloadxmlgraphics-fop-f466690aaeed2dc93360d5f5f14fede90f2f5ad2.tar.gz
xmlgraphics-fop-f466690aaeed2dc93360d5f5f14fede90f2f5ad2.zip
Committing in preparation for trunk merge.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@641873 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
-rw-r--r--src/java/org/apache/fop/image/AbstractFopImage.java4
-rw-r--r--src/java/org/apache/fop/image/FopImage.java4
-rw-r--r--src/java/org/apache/fop/render/afp/AFPGraphics2D.java157
-rw-r--r--src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java7
-rw-r--r--src/java/org/apache/fop/render/afp/AFPInfo.java124
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRenderer.java1099
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java30
-rw-r--r--src/java/org/apache/fop/render/afp/AFPSVGHandler.java91
-rw-r--r--src/java/org/apache/fop/render/afp/AFPState.java198
-rw-r--r--src/java/org/apache/fop/render/afp/DataObjectParameters.java173
-rw-r--r--src/java/org/apache/fop/render/afp/ImageObjectParameters.java138
-rw-r--r--src/java/org/apache/fop/render/afp/ResourceLevel.java123
-rwxr-xr-xsrc/java/org/apache/fop/render/afp/extensions/AFPAttribute.java4
-rwxr-xr-xsrc/java/org/apache/fop/render/afp/extensions/AFPElement.java4
-rwxr-xr-xsrc/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java3
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java155
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java4
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java100
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java9
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java79
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AFPDataStream.java313
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java18
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java2
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractEnvironmentGroup.java100
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java40
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java152
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractPreparedAFPObject.java83
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java108
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java124
-rw-r--r--src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java192
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java198
-rw-r--r--src/java/org/apache/fop/render/afp/modca/Document.java100
-rw-r--r--src/java/org/apache/fop/render/afp/modca/GraphicsObject.java34
-rw-r--r--src/java/org/apache/fop/render/afp/modca/IMImageObject.java46
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ImageContent.java78
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ImageSegment.java65
-rw-r--r--src/java/org/apache/fop/render/afp/modca/IncludeObject.java220
-rw-r--r--src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java11
-rw-r--r--src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java18
-rw-r--r--src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java26
-rw-r--r--src/java/org/apache/fop/render/afp/modca/MapCodedFont.java2
-rw-r--r--src/java/org/apache/fop/render/afp/modca/MapDataResource.java72
-rw-r--r--src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java20
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java4
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java6
-rw-r--r--src/java/org/apache/fop/render/afp/modca/Overlay.java52
-rw-r--r--src/java/org/apache/fop/render/afp/modca/PageGroup.java107
-rw-r--r--src/java/org/apache/fop/render/afp/modca/PageObject.java79
-rw-r--r--src/java/org/apache/fop/render/afp/modca/PageSegment.java102
-rw-r--r--src/java/org/apache/fop/render/afp/modca/PreprocessPresentationObject.java153
-rw-r--r--src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java93
-rw-r--r--src/java/org/apache/fop/render/afp/modca/Registry.java353
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ResourceEnvironmentGroup.java158
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ResourceGroup.java257
-rw-r--r--src/java/org/apache/fop/render/afp/modca/ResourceObject.java180
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java102
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/MeasurementUnitsTriplet.java50
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/ObjectAreaSizeTriplet.java49
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java70
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/ResourceObjectTypeTriplet.java21
-rw-r--r--src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java158
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java9
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java4
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java4
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java4
65 files changed, 4772 insertions, 1771 deletions
diff --git a/src/java/org/apache/fop/image/AbstractFopImage.java b/src/java/org/apache/fop/image/AbstractFopImage.java
index 8d5180149..68949b9c9 100644
--- a/src/java/org/apache/fop/image/AbstractFopImage.java
+++ b/src/java/org/apache/fop/image/AbstractFopImage.java
@@ -360,7 +360,7 @@ public abstract class AbstractFopImage implements FopImage {
* Return the original image data (compressed).
* @return the original image data
*/
- public byte[] getRessourceBytes() {
+ public byte[] getResourceBytes() {
return raw;
}
@@ -368,7 +368,7 @@ public abstract class AbstractFopImage implements FopImage {
* Return the original image data size (compressed).
* @return the original image data size
*/
- public int getRessourceBytesSize() {
+ public int getResourceBytesSize() {
return (raw != null ? raw.length : 0);
}
diff --git a/src/java/org/apache/fop/image/FopImage.java b/src/java/org/apache/fop/image/FopImage.java
index 0f780ad57..abe11ef25 100644
--- a/src/java/org/apache/fop/image/FopImage.java
+++ b/src/java/org/apache/fop/image/FopImage.java
@@ -168,13 +168,13 @@ public interface FopImage {
* Returns the encoded/compressed image as an array of bytes.
* @return the raw image
*/
- byte[] getRessourceBytes();
+ byte[] getResourceBytes();
/**
* Returns the number of bytes of the raw image.
* @return the size in bytes
*/
- int getRessourceBytesSize();
+ int getResourceBytesSize();
/**
* Image info class.
diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPGraphics2D.java
index 3e477e224..974155630 100644
--- a/src/java/org/apache/fop/render/afp/AFPGraphics2D.java
+++ b/src/java/org/apache/fop/render/afp/AFPGraphics2D.java
@@ -44,14 +44,14 @@ import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.modca.AFPDataStream;
+import org.apache.fop.render.afp.goca.GraphicsSetLineType;
import org.apache.fop.render.afp.modca.GraphicsObject;
-import org.apache.fop.render.afp.modca.ImageObject;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetLineType;
+import org.apache.fop.render.afp.modca.IncludeObject;
import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.java2d.StrokingTextHandler;
import org.apache.xmlgraphics.java2d.TextHandler;
+import org.apache.xmlgraphics.ps.ImageEncodingHelper;
/**
* This is a concrete implementation of <tt>AbstractGraphics2D</tt> (and
@@ -78,6 +78,9 @@ public class AFPGraphics2D extends AbstractGraphics2D {
/** Current AFP state */
private AFPState afpState = null;
+ /** The SVG document URI */
+ private String documentURI = null;
+
/**
* @param textAsShapes
* if true, all text is turned into shapes in the convertion. No
@@ -295,7 +298,7 @@ public class AFPGraphics2D extends AbstractGraphics2D {
graphicsObj.addBox(coords);
} else if (shape instanceof Ellipse2D) {
Ellipse2D elip = (Ellipse2D) shape;
- final double factor = afpInfo.resolution / 100f;
+ final double factor = afpInfo.getResolution() / 100f;
graphicsObj.setArcParams(
(int)Math.round(elip.getWidth() * factor),
(int)Math.round(elip.getHeight() * factor),
@@ -345,26 +348,13 @@ public class AFPGraphics2D extends AbstractGraphics2D {
*/
public void handleIOException(IOException ioe) {
// TODO Surely, there's a better way to do this.
+ log.error(ioe.getMessage());
ioe.printStackTrace();
}
/**
* {@inheritDoc}
*/
- public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
- log.debug("drawRenderableImage() NYI: img=" + img + ", xform=" + xform);
- }
-
- /**
- * {@inheritDoc}
- */
- public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
- log.debug("drawRenderedImage() NYI: img=" + img + ", xform=" + xform);
- }
-
- /**
- * {@inheritDoc}
- */
public void drawString(String s, float x, float y) {
try {
if (customTextHandler != null && !textAsShapes) {
@@ -402,7 +392,7 @@ public class AFPGraphics2D extends AbstractGraphics2D {
* {@inheritDoc}
*/
public void dispose() {
- log.debug("dispose() NYI: ");
+ this.graphicsObj = null;
}
/**
@@ -411,54 +401,62 @@ public class AFPGraphics2D extends AbstractGraphics2D {
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), observer);
}
-
+
/**
* {@inheritDoc}
*/
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer) {
- log.debug("drawImage() img=" + img + ", x=" + x + ", y=" + y
+ //TODO: this might be achieved by creating a new IOCA image (ImageObject)
+ // and placing it in an Overlay - but then stacking order would not be preserved.
+ log.debug("drawImage(): NYI img=" + img + ", x=" + x + ", y=" + y
+ ", width=" + width + ", height=" + height + ", obs=" + observer);
-
- int afpres = afpInfo.resolution;
- int afpBitsPerPixel = afpInfo.bitsPerPixel;
- int afpx = x;
- int afpy = y;
- int afpw = width;
- int afph = height;
- boolean colorImages = !afpInfo.grayscale;
- int imageResolution = afpres;
- if (img instanceof BufferedImage) {
- BufferedImage bi = (BufferedImage)img;
- ByteArrayOutputStream baout = new ByteArrayOutputStream();
- try {
- // Serialize image
- AFPRenderer.writeImage(bi, baout);
- byte[] buf = baout.toByteArray();
-
- // Generate image
- AFPDataStream afpDataStream = afpInfo.afpDataStream;
- ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
- afph, afpres, afpres);
- io.setImageParameters(imageResolution, imageResolution,
- afpw, afph);
- if (colorImages) {
- io.setImageIDESize((byte)24);
- io.setImageData(buf);
- } else {
- AFPRenderer.convertToGrayScaleImage(io, buf, afpw, afph, afpBitsPerPixel);
- }
- } catch (IOException ioe) {
- log.error("Error while serializing bitmap: " + ioe.getMessage(),
- ioe);
- return false;
- }
- return true;
- } else {
- log.debug("drawImage() NYI: img=" + img + ", x=" + x + ", y=" + y
- + ", observer=" + observer);
- }
return false;
+// log.debug("drawImage() img=" + img + ", x=" + x + ", y=" + y
+// + ", width=" + width + ", height=" + height + ", obs=" + observer);
+// if (img instanceof BufferedImage) {
+// try {
+// BufferedImage bi = (BufferedImage)img;
+// ByteArrayOutputStream baout = new ByteArrayOutputStream();
+//
+// // Serialize image
+// ImageEncodingHelper.encodeRenderedImageAsRGB(bi, baout);
+//
+// int res = afpInfo.getResolution();
+// ImageObjectParameters params = new ImageObjectParameters(
+// //TODO: provide a real url
+// img.toString(), x, y,
+// width, height, res, res, baout.toByteArray(),
+// img.getWidth(observer), img.getHeight(observer),
+// afpInfo.isColorSupported(), afpInfo.getBitsPerPixel());
+//
+// afpInfo.getAFPDataStream().createImageObject(params);
+//
+// // Generate image
+// } catch (IOException ioe) {
+// log.error("Error while serializing bitmap: " + ioe.getMessage(),
+// ioe);
+// return false;
+// }
+// return true;
+// } else {
+// log.debug("drawImage() image type not supported: " + img);
+// }
+// return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+ log.debug("drawRenderableImage() NYI: img=" + img + ", xform=" + xform);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+ log.debug("drawRenderedImage() NYI: img=" + img + ", xform=" + xform);
}
/**
@@ -489,18 +487,39 @@ public class AFPGraphics2D extends AbstractGraphics2D {
}
/**
+ * Sets the SVG document URI
+ * @param documentURI the SVG document URI
+ */
+ public void setDocumentURI(String documentURI) {
+ this.documentURI = documentURI;
+ }
+
+ /**
* @return the GOCA graphics object
*/
protected GraphicsObject getGraphicsObject() {
- if (this.graphicsObj == null) {
- int x = (int)Math.round((afpInfo.currentXPosition * 25.4f) / 1000);
- int y = (int)Math.round((afpInfo.currentYPosition * 25.4f) / 1000);
- int res = afpInfo.resolution;
- int width = (int)Math.round((afpInfo.width * res) / 72000f);
- int height = (int)Math.round((afpInfo.height * res) / 72000f);
- this.graphicsObj = afpInfo.getAFPDataStream().getGraphicsObject(
- x, y, width, height, res, res);
- }
+// if (this.graphicsObj == null) {
+//// DataObjectParameters params = new DataObjectParameters(
+//// ((AbstractDocument)doc).getDocumentURI(),
+//// afpInfo.getX(), afpInfo.getY(),
+//// afpInfo.getWidth(), afpInfo.getHeight(), res, res);
+////
+//// afpInfo.getAFPDataStream().createGraphicsObject(params);
+//
+// int x = (int)Math.round((afpInfo.getX() * 25.4f) / 1000);
+// int y = (int)Math.round((afpInfo.getY() * 25.4f) / 1000);
+// int res = afpInfo.getResolution();
+// int width = (int)Math.round((afpInfo.getWidth() * res) / 72000f);
+// int height = (int)Math.round((afpInfo.getHeight() * res) / 72000f);
+// DataObjectParameters params = new DataObjectParameters(
+// this.documentURI, x, y, width, height, res, res);
+// IncludeObject includeObj = afpInfo.getAFPDataStream().createGraphicsObject(params);
+// this.graphicsObj = (GraphicsObject)includeObj.getReferencedObject();
+// }
return this.graphicsObj;
}
+
+ protected void setGraphicsObject(GraphicsObject graphicsObj) {
+ this.graphicsObj = graphicsObj;
+ }
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
index 687a0373e..1abe7c0d1 100644
--- a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
+++ b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
@@ -51,8 +51,11 @@ public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter {
//Paint to a BufferedImage
int resolution = (int)Math.round(context.getUserAgent().getTargetResolution());
BufferedImage bi = paintToBufferedImage(painter, wrappedContext, resolution, gray, false);
-
- afp.drawBufferedImage(bi, resolution, x, y, width, height);
+
+ //TODO: uri
+ String uri = null;
+ java.util.Map foreignAttributes = null;
+ afp.drawBufferedImage(uri, bi, resolution, x, y, width, height, foreignAttributes);
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPInfo.java b/src/java/org/apache/fop/render/afp/AFPInfo.java
index 026ab4dfe..19e58d30f 100644
--- a/src/java/org/apache/fop/render/afp/AFPInfo.java
+++ b/src/java/org/apache/fop/render/afp/AFPInfo.java
@@ -28,28 +28,28 @@ import org.apache.fop.render.afp.modca.AFPDataStream;
*/
public final class AFPInfo {
/** see WIDTH */
- protected int width;
+ private int width;
/** see HEIGHT */
- protected int height;
+ private int height;
/** see XPOS */
- protected int currentXPosition;
+ private int x;
/** see YPOS */
- protected int currentYPosition;
+ private int y;
/** see HANDLER_CONFIGURATION */
- protected Configuration cfg;
+ private Configuration cfg;
/** see AFP_FONT_INFO */
- protected FontInfo fontInfo;
+ private FontInfo fontInfo;
/** See AFP_DATASTREAM */
- protected AFPDataStream afpDataStream;
+ private AFPDataStream afpDataStream;
/** See AFP_STATE */
- protected AFPState afpState;
+ private AFPState afpState;
/** see AFP_GRAYSCALE */
- protected boolean grayscale;
+ private boolean color;
/** see AFP_RESOLUTION */
- protected int resolution;
+ private int resolution;
/** see AFP_BITS_PER_PIXEL */
- protected int bitsPerPixel;
+ private int bitsPerPixel;
/**
* Returns the width.
@@ -91,6 +91,14 @@ public final class AFPInfo {
}
/**
+ * Sets the handler configuration
+ * @param cfg the handler configuration
+ */
+ public void setHandlerConfiguration(Configuration cfg) {
+ this.cfg = cfg;
+ }
+
+ /**
* @return FontInfo the font info
*/
public FontInfo getFontInfo() {
@@ -115,6 +123,98 @@ public final class AFPInfo {
* @return true if supports color
*/
public boolean isColorSupported() {
- return !this.grayscale;
+ return this.color;
+ }
+
+ /**
+ * @return the current x position coordinate
+ */
+ protected int getX() {
+ return x;
+ }
+
+ /**
+ * @return the current y position coordinate
+ */
+ protected int getY() {
+ return y;
+ }
+
+ /**
+ * @return the resolution
+ */
+ protected int getResolution() {
+ return resolution;
+ }
+
+ /**
+ * @return the number of bits per pixel to use
+ */
+ protected int getBitsPerPixel() {
+ return bitsPerPixel;
+ }
+
+ /**
+ * Sets the current x position coordinate
+ * @param x the current x position coordinate
+ */
+ protected void setX(int x) {
+ this.x = x;
+ }
+
+ /**
+ * Sets the current y position coordinate
+ * @param y the current y position coordinate
+ */
+ protected void setY(int y) {
+ this.y = y;
+ }
+
+ /**
+ * Sets the current resolution
+ * @param resolution the current resolution
+ */
+ protected void setResolution(int resolution) {
+ this.resolution = resolution;
+ }
+
+ /**
+ * Sets the current font info
+ * @param fontInfo the current font info
+ */
+ protected void setFontInfo(FontInfo fontInfo) {
+ this.fontInfo = fontInfo;
+ }
+
+ /**
+ * Sets the AFP state
+ * @param state the AFP state
+ */
+ public void setState(AFPState state) {
+ this.afpState = state;
+ }
+
+ /**
+ * Sets the AFP datastream
+ * @param afpDataStream the AFP datastream
+ */
+ public void setAFPDataStream(AFPDataStream afpDataStream) {
+ this.afpDataStream = afpDataStream;
+ }
+
+ /**
+ * Sets if we are supporing color
+ * @param color true if color is supported
+ */
+ public void setColor(boolean color) {
+ this.color = color;
+ }
+
+ /**
+ * Sets the number of bits per pixel
+ * @param bitsPerPixel the number of bits per pixel
+ */
+ public void setBitsPerPixel(int bitsPerPixel) {
+ this.bitsPerPixel = bitsPerPixel;
}
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java
index 5cdd55d98..b10f4b30f 100644
--- a/src/java/org/apache/fop/render/afp/AFPRenderer.java
+++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java
@@ -23,6 +23,7 @@ import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.io.FileNotFoundException;
@@ -30,8 +31,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -39,7 +38,6 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -58,6 +56,7 @@ import org.apache.fop.area.Block;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
+import org.apache.fop.area.LineArea;
import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionReference;
@@ -89,6 +88,7 @@ import org.apache.fop.render.afp.fonts.OutlineFont;
import org.apache.fop.render.afp.modca.AFPConstants;
import org.apache.fop.render.afp.modca.AFPDataStream;
import org.apache.fop.render.afp.modca.ImageObject;
+import org.apache.fop.render.afp.modca.IncludeObject;
import org.apache.fop.render.afp.modca.PageObject;
/**
@@ -139,28 +139,23 @@ import org.apache.fop.render.afp.modca.PageObject;
* handle all types of inline area, text, image etc and draws various lines and
* rectangles.
* </p>
- *
- * Note: There are specific extensions that have been added to the FO. They are
- * specific to their location within the FO and have to be processed accordingly
- * (ie. at the start or end of the page).
- *
+ *
+ * Note: There are specific extensions that have been added to the
+ * FO. They are specific to their location within the FO and have to be
+ * processed accordingly (ie. at the start or end of the page).
+ *
*/
public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
- * 2400 dpi renderer resolution
- */
- protected static final int DPI_240_RESOLUTION = 240;
-
- /**
- * 14400 dpi renderer resolution
+ * The default afp renderer output resolution
*/
- protected static final int DPI_1440_RESOLUTION = 1440;
+ public static final int DPI_240_RESOLUTION = 240;
/**
* The afp factor for calculating resolutions (e.g. 72000/240 = 300)
*/
- protected static final int DPI_CONVERSION_FACTOR = 72000;
+ private static final int DPI_CONVERSION_FACTOR = 72000;
/**
* The afp data stream object responsible for generating afp data
@@ -168,11 +163,46 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
private AFPDataStream afpDataStream = null;
/**
+ * The map of afp root extensions
+ */
+ // UNUSED
+ // private HashMap rootExtensionMap = null;
+ /**
* The map of page segments
*/
private Map pageSegmentsMap = null;
/**
+ * The fonts on the current page
+ */
+ private Map currentPageFonts = null;
+
+ /**
+ * The current color object
+ */
+ private Color currentColor = null;
+
+ /**
+ * The page font number counter, used to determine the next font reference
+ */
+ private int pageFontCounter = 0;
+
+ /**
+ * The current font family
+ */
+ // UNUSED
+ // private String currentFontFamily = "";
+ /**
+ * The current font size
+ */
+ private int currentFontSize = 0;
+
+ /**
+ * The Options to be set on the AFPRenderer
+ */
+ // UNUSED
+ // private Map afpOptions = null;
+ /**
* The page width
*/
private int pageWidth = 0;
@@ -183,6 +213,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
private int pageHeight = 0;
/**
+ * The current page sequence id
+ */
+ // UNUSED
+ // private String pageSequenceId = null;
+ /**
* The portrait rotation
*/
private int portraitRotation = 0;
@@ -193,6 +228,21 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
private int landscapeRotation = 270;
/**
+ * The line cache, avoids drawing duplicate lines in tables.
+ */
+ // UNUSED
+ // private HashSet lineCache = null;
+ /**
+ * The current x position for line drawing
+ */
+ // UNUSED
+ // private float x;
+ /**
+ * The current y position for line drawing
+ */
+ // UNUSED
+ // private float y;
+ /**
* The map of saved incomplete pages
*/
private Map pages = null;
@@ -213,7 +263,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
private int resolution = DPI_240_RESOLUTION;
/** drawing state */
- protected AFPState currentState = null;
+ private AFPState currentState = null;
/**
* Constructor for AFPRenderer.
@@ -224,22 +274,20 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Set up the font info
- *
- * @param inFontInfo
- * font info to set up
+ *
+ * @param inFontInfo font info to set up
*/
public void setupFontInfo(FontInfo inFontInfo) {
this.fontInfo = inFontInfo;
int num = 1;
if (this.fontList != null && this.fontList.size() > 0) {
for (Iterator it = this.fontList.iterator(); it.hasNext();) {
- AFPFontInfo afi = (AFPFontInfo) it.next();
- AFPFont bf = (AFPFont) afi.getAFPFont();
- for (Iterator it2 = afi.getFontTriplets().iterator(); it2
- .hasNext();) {
- FontTriplet ft = (FontTriplet) it2.next();
- this.fontInfo.addFontProperties("F" + num, ft.getName(), ft
- .getStyle(), ft.getWeight());
+ AFPFontInfo afi = (AFPFontInfo)it.next();
+ AFPFont bf = (AFPFont)afi.getAFPFont();
+ for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext();) {
+ FontTriplet ft = (FontTriplet)it2.next();
+ this.fontInfo.addFontProperties("F" + num, ft.getName()
+ , ft.getStyle(), ft.getWeight());
this.fontInfo.addMetrics("F" + num, bf);
num++;
}
@@ -248,36 +296,33 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
log.warn("No AFP fonts configured - using default setup");
}
if (this.fontInfo.fontLookup("sans-serif", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
- "CZH200 ", 1, new Helvetica());
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZH200 ",
+ 1, new Helvetica());
AFPFont bf = new OutlineFont("Helvetica", cs);
- this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal",
- 400);
+ this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal", 400);
this.fontInfo.addMetrics("F" + num, bf);
num++;
}
if (this.fontInfo.fontLookup("serif", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
- "CZN200 ", 1, new TimesRoman());
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZN200 ",
+ 1, new TimesRoman());
AFPFont bf = new OutlineFont("Helvetica", cs);
this.fontInfo.addFontProperties("F" + num, "serif", "normal", 400);
this.fontInfo.addMetrics("F" + num, bf);
num++;
}
if (this.fontInfo.fontLookup("monospace", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500",
- "CZ4200 ", 1, new Courier());
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZ4200 ",
+ 1, new Courier());
AFPFont bf = new OutlineFont("Helvetica", cs);
- this.fontInfo.addFontProperties("F" + num, "monospace", "normal",
- 400);
+ this.fontInfo.addFontProperties("F" + num, "monospace", "normal", 400);
this.fontInfo.addMetrics("F" + num, bf);
num++;
}
if (this.fontInfo.fontLookup("any", "normal", 400) == null) {
- FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal",
- 400);
- this.fontInfo.addFontProperties(this.fontInfo
- .getInternalFontKey(ft), "any", "normal", 400);
+ FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal", 400);
+ this.fontInfo.addFontProperties(
+ this.fontInfo.getInternalFontKey(ft), "any", "normal", 400);
}
}
@@ -292,54 +337,62 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* {@inheritDoc}
*/
public void startRenderer(OutputStream outputStream) throws IOException {
- this.currentState = new AFPState();
- this.afpDataStream = new AFPDataStream();
- this.afpDataStream.setPortraitRotation(portraitRotation);
- this.afpDataStream.setLandscapeRotation(landscapeRotation);
- this.afpDataStream.startDocument(outputStream);
+ currentPageFonts = new java.util.HashMap();
+ currentColor = new Color(255, 255, 255);
+ afpDataStream = new AFPDataStream();
+ afpDataStream.setPortraitRotation(portraitRotation);
+ afpDataStream.setLandscapeRotation(landscapeRotation);
+ afpDataStream.setOutputStream(outputStream);
}
/**
* {@inheritDoc}
*/
public void stopRenderer() throws IOException {
- this.afpDataStream.endDocument();
+ afpDataStream.write();
}
/**
* {@inheritDoc}
*/
public boolean supportsOutOfOrder() {
- // return false;
+ //return false;
return true;
}
/**
- * Prepare a page for rendering. This is called if the renderer supports out
- * of order rendering. The renderer should prepare the page so that a page
- * further on in the set of pages can be rendered. The body of the page
- * should not be rendered. The page will be rendered at a later time by the
- * call to render page.
- *
+ * Prepare a page for rendering. This is called if the renderer supports
+ * out of order rendering. The renderer should prepare the page so that a
+ * page further on in the set of pages can be rendered. The body of the
+ * page should not be rendered. The page will be rendered at a later time
+ * by the call to render page.
+ *
* {@inheritDoc}
*/
public void preparePage(PageViewport page) {
+ // initializeRootExtensions(page);
- this.currentState.reset();
+ // this.currentFontFamily = "";
+ this.currentFontSize = 0;
+ this.pageFontCounter = 0;
+ this.currentPageFonts.clear();
+ // this.lineCache = new HashSet();
Rectangle2D bounds = page.getViewArea();
this.pageWidth = mpts2units(bounds.getWidth());
this.pageHeight = mpts2units(bounds.getHeight());
+ // renderPageGroupExtensions(page);
+
final int pageRotation = 0;
this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
- this.resolution, this.resolution);
+ getResolution(), getResolution());
renderPageObjectExtensions(page);
if (this.pages == null) {
- this.pages = new HashMap();
+ this.pages = new java.util.HashMap();
}
this.pages.put(page, afpDataStream.savePage());
@@ -372,15 +425,12 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
}
/**
- * Renders a region viewport.
- * <p>
- *
- * The region may clip the area and it establishes a position from where the
- * region is placed.
- * </p>
- *
- * @param port
- * The region viewport to be rendered
+ * Renders a region viewport. <p>
+ *
+ * The region may clip the area and it establishes a position from where
+ * the region is placed.</p>
+ *
+ * @param port The region viewport to be rendered
*/
public void renderRegionViewport(RegionViewport port) {
if (port != null) {
@@ -395,9 +445,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
handleRegionTraits(port);
/*
- * _afpDataStream.startOverlay(mpts2units(view.getX()) ,
- * mpts2units(view.getY()) , mpts2units(view.getWidth()) ,
- * mpts2units(view.getHeight()) , rotation);
+ _afpDataStream.startOverlay(mpts2units(view.getX())
+ , mpts2units(view.getY())
+ , mpts2units(view.getWidth())
+ , mpts2units(view.getHeight())
+ , rotation);
*/
pushViewPortPos(new ViewPortPos(view, regionReference.getCTM()));
@@ -408,7 +460,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
renderRegion(regionReference);
}
/*
- * _afpDataStream.endOverlay();
+ _afpDataStream.endOverlay();
*/
popViewPortPos();
}
@@ -423,65 +475,77 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
// save positions
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
- // String saveFontName = currentFontName;
CTM ctm = bv.getCTM();
int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
- float x, y;
- x = (float) (bv.getXOffset() + containingIPPosition) / 1000f;
- y = (float) (bv.getYOffset() + containingBPPosition) / 1000f;
- // This is the content-rect
- float width = (float) bv.getIPD() / 1000f;
- float height = (float) bv.getBPD() / 1000f;
+ //This is the content-rect
+ float width = (float)bv.getIPD() / 1000f;
+ float height = (float)bv.getBPD() / 1000f;
if (bv.getPositioning() == Block.ABSOLUTE
|| bv.getPositioning() == Block.FIXED) {
- currentIPPosition = bv.getXOffset();
- currentBPPosition = bv.getYOffset();
-
- // For FIXED, we need to break out of the current viewports to the
- // one established by the page. We save the state stack for
- // restoration
- // after the block-container has been painted. See below.
+ //For FIXED, we need to break out of the current viewports to the
+ //one established by the page. We save the state stack for restoration
+ //after the block-container has been painted. See below.
List breakOutList = null;
if (bv.getPositioning() == Block.FIXED) {
breakOutList = breakOutOfStateStack();
}
- CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
- ctm = tempctm.multiply(ctm);
-
- // Adjust for spaces (from margin or indirectly by start-indent etc.
- x += bv.getSpaceStart() / 1000f;
- currentIPPosition += bv.getSpaceStart();
-
- y += bv.getSpaceBefore() / 1000f;
- currentBPPosition += bv.getSpaceBefore();
-
- float bpwidth = (borderPaddingStart + bv
- .getBorderAndPaddingWidthEnd()) / 1000f;
- float bpheight = (borderPaddingBefore + bv
- .getBorderAndPaddingWidthAfter()) / 1000f;
-
- drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
-
- // Now adjust for border/padding
- currentIPPosition += borderPaddingStart;
- currentBPPosition += borderPaddingBefore;
+ AffineTransform positionTransform = new AffineTransform();
+ positionTransform.translate(bv.getXOffset(), bv.getYOffset());
+
+ //"left/"top" (bv.getX/YOffset()) specify the position of the content rectangle
+ positionTransform.translate(-borderPaddingStart, -borderPaddingBefore);
- Rectangle2D clippingRect = null;
- clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
- bv.getIPD(), bv.getBPD());
+ //skipping fox:transform here
- // startVParea(ctm, clippingRect);
- pushViewPortPos(new ViewPortPos(clippingRect, ctm));
+ //saveGraphicsState();
+ //Viewport position
+ //concatenateTransformationMatrix(mptToPt(positionTransform));
+
+ //Background and borders
+ float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+ float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+ Point2D ptSrc = new Point(0, 0);
+ Point2D ptDst = positionTransform.transform(ptSrc, null);
+ Rectangle2D borderRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(),
+ 1000 * (width + bpwidth), 1000 * (height + bpheight));
+ pushViewPortPos(new ViewPortPos(borderRect, new CTM(positionTransform)));
+ drawBackAndBorders(bv, 0, 0, width + bpwidth, height + bpheight);
+
+ //Shift to content rectangle after border painting
+ AffineTransform contentRectTransform = new AffineTransform();
+ contentRectTransform.translate(borderPaddingStart, borderPaddingBefore);
+ //concatenateTransformationMatrix(mptToPt(contentRectTransform));
+ ptSrc = new Point(0, 0);
+ ptDst = contentRectTransform.transform(ptSrc, null);
+ Rectangle2D contentRect = new Rectangle2D.Double(ptDst.getX(), ptDst.getY(),
+ 1000 * width, 1000 * height);
+ pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentRectTransform)));
+
+ //Clipping is not supported, yet
+ //Rectangle2D clippingRect = null;
+ //clippingRect = new Rectangle(0, 0, bv.getIPD(), bv.getBPD());
+
+ //saveGraphicsState();
+ //Set up coordinate system for content rectangle
+ AffineTransform contentTransform = ctm.toAffineTransform();
+ //concatenateTransformationMatrix(mptToPt(contentTransform));
+ contentRect = new Rectangle2D.Double(0, 0, 1000 * width, 1000 * height);
+ pushViewPortPos(new ViewPortPos(contentRect, new CTM(contentTransform)));
+
currentIPPosition = 0;
currentBPPosition = 0;
renderBlocks(bv, children);
- // endVParea();
+
popViewPortPos();
+ popViewPortPos();
+ //restoreGraphicsState();
+ popViewPortPos();
+ //restoreGraphicsState();
if (breakOutList != null) {
restoreStateStackAfterBreakOut(breakOutList);
@@ -493,37 +557,36 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
currentBPPosition += bv.getSpaceBefore();
- // borders and background in the old coordinate system
+ //borders and background in the old coordinate system
handleBlockTraits(bv);
- // Advance to start of content area
+ //Advance to start of content area
currentIPPosition += bv.getStartIndent();
CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
ctm = tempctm.multiply(ctm);
- // Now adjust for border/padding
+ //Now adjust for border/padding
currentBPPosition += borderPaddingBefore;
Rectangle2D clippingRect = null;
clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
bv.getIPD(), bv.getBPD());
- // startVParea(ctm, clippingRect);
+ //startVParea(ctm, clippingRect);
pushViewPortPos(new ViewPortPos(clippingRect, ctm));
currentIPPosition = 0;
currentBPPosition = 0;
renderBlocks(bv, children);
- // endVParea();
+ //endVParea();
popViewPortPos();
currentIPPosition = saveIP;
currentBPPosition = saveBP;
- currentBPPosition += (int) (bv.getAllocBPD());
+ currentBPPosition += (int)(bv.getAllocBPD());
}
- // currentFontName = saveFontName;
}
/** {@inheritDoc} */
@@ -537,7 +600,13 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
*/
public void renderPage(PageViewport pageViewport) {
- currentState.reset();
+ // initializeRootExtensions(page);
+
+ // this.currentFontFamily = "";
+ this.currentFontSize = 0;
+ this.pageFontCounter = 0;
+ this.currentPageFonts.clear();
+ // this.lineCache = new HashSet();
Rectangle2D bounds = pageViewport.getViewArea();
@@ -546,14 +615,14 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
if (pages != null && pages.containsKey(pageViewport)) {
- this.afpDataStream.restorePage((PageObject) pages
- .remove(pageViewport));
+ this.afpDataStream.restorePage((PageObject) pages.remove(pageViewport));
} else {
+ // renderPageGroupExtensions(page);
final int pageRotation = 0;
this.afpDataStream.startPage(pageWidth, pageHeight, pageRotation,
- this.resolution, this.resolution);
+ getResolution(), getResolution());
renderPageObjectExtensions(pageViewport);
@@ -563,16 +632,20 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
renderPageAreas(pageViewport.getPage());
- this.afpDataStream.addFontsToCurrentPage(currentState.getPageFonts());
+ Iterator i = currentPageFonts.values().iterator();
+ while (i.hasNext()) {
+ AFPFontAttributes afpFontAttributes = (AFPFontAttributes) i.next();
+
+ afpDataStream.createFont(
+ (byte)afpFontAttributes.getFontReference(),
+ afpFontAttributes.getFont(),
+ afpFontAttributes.getPointSize());
- try {
- afpDataStream.endPage();
- } catch (IOException ioex) {
- // TODO What shall we do?
}
+ afpDataStream.endPage();
+
popViewPortPos();
-
}
/**
@@ -615,12 +688,22 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
*/
public void fillRect(float x, float y, float width, float height) {
/*
- * afpDataStream.createShading( pts2units(x), pts2units(y),
- * pts2units(width), pts2units(height), currentColor.getRed(),
- * currentColor.getGreen(), currentColor.getBlue());
+ afpDataStream.createShading(
+ pts2units(x),
+ pts2units(y),
+ pts2units(width),
+ pts2units(height),
+ currentColor.getRed(),
+ currentColor.getGreen(),
+ currentColor.getBlue());
*/
- afpDataStream.createLine(pts2units(x), pts2units(y), pts2units(x
- + width), pts2units(y), pts2units(height), currentState.getColor());
+ afpDataStream.createLine(
+ pts2units(x),
+ pts2units(y),
+ pts2units(x + width),
+ pts2units(y),
+ pts2units(height),
+ currentColor);
}
/**
@@ -635,112 +718,193 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
return;
}
switch (style) {
- case Constants.EN_DOUBLE:
- if (horz) {
- float h3 = h / 3;
- float ym1 = y1;
- float ym2 = ym1 + h3 + h3;
- afpDataStream.createLine(pts2units(x1), pts2units(ym1),
- pts2units(x2), pts2units(ym1), pts2units(h3), col);
- afpDataStream.createLine(pts2units(x1), pts2units(ym2),
- pts2units(x2), pts2units(ym2), pts2units(h3), col);
- } else {
- float w3 = w / 3;
- float xm1 = x1;
- float xm2 = xm1 + w3 + w3;
- afpDataStream.createLine(pts2units(xm1), pts2units(y1),
- pts2units(xm1), pts2units(y2), pts2units(w3), col);
- afpDataStream.createLine(pts2units(xm2), pts2units(y1),
- pts2units(xm2), pts2units(y2), pts2units(w3), col);
- }
- break;
- case Constants.EN_DASHED:
- if (horz) {
- float w2 = 2 * h;
- while (x1 + w2 < x2) {
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
- pts2units(x1 + w2), pts2units(y1), pts2units(h),
- col);
- x1 += 2 * w2;
+ case Constants.EN_DOUBLE:
+ if (horz) {
+ float h3 = h / 3;
+ float ym1 = y1;
+ float ym2 = ym1 + h3 + h3;
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1),
+ pts2units(x2),
+ pts2units(ym1),
+ pts2units(h3),
+ col
+ );
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym2),
+ pts2units(x2),
+ pts2units(ym2),
+ pts2units(h3),
+ col
+ );
+ } else {
+ float w3 = w / 3;
+ float xm1 = x1;
+ float xm2 = xm1 + w3 + w3;
+ afpDataStream.createLine(
+ pts2units(xm1),
+ pts2units(y1),
+ pts2units(xm1),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
+ afpDataStream.createLine(
+ pts2units(xm2),
+ pts2units(y1),
+ pts2units(xm2),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
}
- } else {
- float h2 = 2 * w;
- while (y1 + h2 < y2) {
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
- pts2units(x1), pts2units(y1 + h2), pts2units(w),
- col);
- y1 += 2 * h2;
+ break;
+ case Constants.EN_DASHED:
+ if (horz) {
+ float w2 = 2 * h;
+ while (x1 + w2 < x2) {
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1 + w2),
+ pts2units(y1),
+ pts2units(h),
+ col
+ );
+ x1 += 2 * w2;
+ }
+ } else {
+ float h2 = 2 * w;
+ while (y1 + h2 < y2) {
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1),
+ pts2units(y1 + h2),
+ pts2units(w),
+ col
+ );
+ y1 += 2 * h2;
+ }
}
- }
- break;
- case Constants.EN_DOTTED:
- if (horz) {
- while (x1 + h < x2) {
- afpDataStream
- .createLine(pts2units(x1), pts2units(y1),
- pts2units(x1 + h), pts2units(y1),
- pts2units(h), col);
- x1 += 2 * h;
+ break;
+ case Constants.EN_DOTTED:
+ if (horz) {
+ while (x1 + h < x2) {
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1 + h),
+ pts2units(y1),
+ pts2units(h),
+ col
+ );
+ x1 += 2 * h;
+ }
+ } else {
+ while (y1 + w < y2) {
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1),
+ pts2units(y1 + w),
+ pts2units(w),
+ col
+ );
+ y1 += 2 * w;
+ }
}
- } else {
- while (y1 + w < y2) {
- afpDataStream
- .createLine(pts2units(x1), pts2units(y1),
- pts2units(x1), pts2units(y1 + w),
- pts2units(w), col);
- y1 += 2 * w;
+ break;
+ case Constants.EN_GROOVE:
+ case Constants.EN_RIDGE:
+ {
+ float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
+ if (horz) {
+ Color uppercol = lightenColor(col, -colFactor);
+ Color lowercol = lightenColor(col, colFactor);
+ float h3 = h / 3;
+ float ym1 = y1;
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1),
+ pts2units(x2),
+ pts2units(ym1),
+ pts2units(h3),
+ uppercol
+ );
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1 + h3),
+ pts2units(x2),
+ pts2units(ym1 + h3),
+ pts2units(h3),
+ col
+ );
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1 + h3 + h3),
+ pts2units(x2),
+ pts2units(ym1 + h3 + h3),
+ pts2units(h3),
+ lowercol
+ );
+ } else {
+ Color leftcol = lightenColor(col, -colFactor);
+ Color rightcol = lightenColor(col, colFactor);
+ float w3 = w / 3;
+ float xm1 = x1 + (w3 / 2);
+ afpDataStream.createLine(
+ pts2units(xm1),
+ pts2units(y1),
+ pts2units(xm1),
+ pts2units(y2),
+ pts2units(w3),
+ leftcol
+ );
+ afpDataStream.createLine(
+ pts2units(xm1 + w3),
+ pts2units(y1),
+ pts2units(xm1 + w3),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
+ afpDataStream.createLine(
+ pts2units(xm1 + w3 + w3),
+ pts2units(y1),
+ pts2units(xm1 + w3 + w3),
+ pts2units(y2),
+ pts2units(w3),
+ rightcol
+ );
}
+ break;
}
- break;
- case Constants.EN_GROOVE:
- case Constants.EN_RIDGE: {
- float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
- if (horz) {
- Color uppercol = lightenColor(col, -colFactor);
- Color lowercol = lightenColor(col, colFactor);
- float h3 = h / 3;
- float ym1 = y1;
- afpDataStream.createLine(pts2units(x1), pts2units(ym1),
- pts2units(x2), pts2units(ym1), pts2units(h3), uppercol);
- afpDataStream.createLine(pts2units(x1), pts2units(ym1 + h3),
- pts2units(x2), pts2units(ym1 + h3), pts2units(h3), col);
- afpDataStream.createLine(pts2units(x1),
- pts2units(ym1 + h3 + h3), pts2units(x2), pts2units(ym1
- + h3 + h3), pts2units(h3), lowercol);
- } else {
- Color leftcol = lightenColor(col, -colFactor);
- Color rightcol = lightenColor(col, colFactor);
- float w3 = w / 3;
- float xm1 = x1 + (w3 / 2);
- afpDataStream.createLine(pts2units(xm1), pts2units(y1),
- pts2units(xm1), pts2units(y2), pts2units(w3), leftcol);
- afpDataStream.createLine(pts2units(xm1 + w3), pts2units(y1),
- pts2units(xm1 + w3), pts2units(y2), pts2units(w3), col);
- afpDataStream.createLine(pts2units(xm1 + w3 + w3),
- pts2units(y1), pts2units(xm1 + w3 + w3), pts2units(y2),
- pts2units(w3), rightcol);
- }
- break;
- }
- case Constants.EN_HIDDEN:
- break;
- case Constants.EN_INSET:
- case Constants.EN_OUTSET:
- default:
- afpDataStream.createLine(pts2units(x1), pts2units(y1),
- pts2units(horz ? x2 : x1), pts2units(horz ? y1 : y2),
- pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))), col);
+ case Constants.EN_HIDDEN:
+ break;
+ case Constants.EN_INSET:
+ case Constants.EN_OUTSET:
+ default:
+ afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(horz ? x2 : x1),
+ pts2units(horz ? y1 : y2),
+ pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))),
+ col
+ );
}
}
/**
* {@inheritDoc}
*/
- protected RendererContext createRendererContext(int x, int y, int width,
- int height, Map foreignAttributes) {
+ protected RendererContext createRendererContext(int x, int y, int width, int height,
+ Map foreignAttributes) {
RendererContext context;
- context = super.createRendererContext(x, y, width, height,
- foreignAttributes);
+ context = super.createRendererContext(x, y, width, height, foreignAttributes);
context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE,
new Boolean(!this.colorImages));
context.setProperty(AFPRendererContextConstants.AFP_FONT_INFO,
@@ -750,9 +914,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
context.setProperty(AFPRendererContextConstants.AFP_BITS_PER_PIXEL,
new Integer(this.bitsPerPixel));
context.setProperty(AFPRendererContextConstants.AFP_DATASTREAM,
- this.afpDataStream);
+ getAFPDataStream());
context.setProperty(AFPRendererContextConstants.AFP_STATE,
- this.currentState);
+ getState());
return context;
}
@@ -763,6 +927,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
ImageFlavor.RENDERED_IMAGE,
ImageFlavor.XML_DOM};
+
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
uri = URISpecification.getURL(uri);
@@ -784,6 +949,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
} else {
ImageManager manager = getUserAgent().getFactory().getImageManager();
ImageInfo info = null;
+ InputStream in = null;
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
info = manager.getImageInfo(uri, sessionContext);
@@ -806,48 +972,62 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
} else if (img instanceof ImageRendered) {
ImageRendered imgRend = (ImageRendered)img;
RenderedImage ri = imgRend.getRenderedImage();
-
- drawBufferedImage(ri, getResolution(),
+ drawBufferedImage(uri, ri, getResolution(),
posInt.x + currentIPPosition,
posInt.y + currentBPPosition,
posInt.width,
- posInt.height);
+ posInt.height, foreignAttributes);
} else if (img instanceof ImageRawCCITTFax) {
ImageRawCCITTFax ccitt = (ImageRawCCITTFax)img;
+ in = ccitt.createInputStream();
+ byte[] buf = IOUtils.toByteArray(in);
int afpx = mpts2units(posInt.x + currentIPPosition);
int afpy = mpts2units(posInt.y + currentBPPosition);
int afpw = mpts2units(posInt.getWidth());
int afph = mpts2units(posInt.getHeight());
int afpres = getResolution();
- ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph,
- afpres, afpres);
- io.setImageParameters(
- (int) (ccitt.getSize().getDpiHorizontal() * 10),
- (int) (ccitt.getSize().getDpiVertical() * 10),
+ ImageObjectParameters params = new ImageObjectParameters(
+ uri, afpx, afpy, afpw, afph, afpres, afpres,
+ buf,
ccitt.getSize().getWidthPx(),
- ccitt.getSize().getHeightPx());
- int compression = ccitt.getCompression();
- switch (compression) {
- case TIFFImage.COMP_FAX_G3_1D :
- io.setImageEncoding((byte) 0x80);
- break;
- case TIFFImage.COMP_FAX_G3_2D :
- io.setImageEncoding((byte) 0x81);
- break;
- case TIFFImage.COMP_FAX_G4_2D :
- io.setImageEncoding((byte) 0x82);
- break;
- default:
- throw new IllegalStateException(
- "Invalid compression scheme: " + compression);
- }
- InputStream in = ccitt.createInputStream();
- try {
- byte[] buf = IOUtils.toByteArray(in);
- io.setImageData(buf);
- } finally {
- IOUtils.closeQuietly(in);
- }
+ ccitt.getSize().getHeightPx(),
+ colorImages, bitsPerPixel
+ );
+ params.setCompression(ccitt.getCompression());
+ params.setResourceLevelFromForeignAttributes(foreignAttributes);
+// params.setData(buf);
+ afpDataStream.createImageObject(params);
+
+
+// ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw, afph,
+// afpres, afpres);
+// io.setImageParameters(
+// (int) (ccitt.getSize().getDpiHorizontal() * 10),
+// (int) (ccitt.getSize().getDpiVertical() * 10),
+// ccitt.getSize().getWidthPx(),
+// ccitt.getSize().getHeightPx());
+// int compression = ccitt.getCompression();
+// switch (compression) {
+// case TIFFImage.COMP_FAX_G3_1D :
+// io.setImageEncoding((byte) 0x80);
+// break;
+// case TIFFImage.COMP_FAX_G3_2D :
+// io.setImageEncoding((byte) 0x81);
+// break;
+// case TIFFImage.COMP_FAX_G4_2D :
+// io.setImageEncoding((byte) 0x82);
+// break;
+// default:
+// throw new IllegalStateException(
+// "Invalid compression scheme: " + compression);
+// }
+// InputStream in = ccitt.createInputStream();
+// try {
+// byte[] buf = IOUtils.toByteArray(in);
+// io.setImageData(buf);
+// } finally {
+// IOUtils.closeQuietly(in);
+// }
} else if (img instanceof ImageXMLDOM) {
ImageXMLDOM imgXML = (ImageXMLDOM)img;
renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(),
@@ -864,6 +1044,10 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
} catch (IOException ioe) {
log.error("I/O error while processing image: "
+ (info != null ? info.toString() : uri), ioe);
+ } finally {
+ if (in != null) {
+ IOUtils.closeQuietly(in);
+ }
}
/*
@@ -906,46 +1090,47 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* io.setImageData(fopimage.getRessourceBytes());
*//*
} else if (MimeConstants.MIME_TIFF.equals(mime)
- && fopimage instanceof TIFFImage) {
+ && fopimage instanceof TIFFImage) {
TIFFImage tiffImage = (TIFFImage) fopimage;
int x = mpts2units(pos.getX() + currentIPPosition);
int y = mpts2units(pos.getY() + currentBPPosition);
int w = mpts2units(pos.getWidth());
int h = mpts2units(pos.getHeight());
- int res = getResolution();
- ImageObject io = afpDataStream.getImageObject(x, y, w, h, res,
- res);
+ ImageObject io = afpDataStream.getImageObject(x, y, w, h,
+ getResolution(), getResolution());
io.setImageParameters(
- (int) (fopimage.getHorizontalResolution() * 10),
- (int) (fopimage.getVerticalResolution() * 10), fopimage
- .getWidth(), fopimage.getHeight());
+ (int)(fopimage.getHorizontalResolution() * 10),
+ (int)(fopimage.getVerticalResolution() * 10),
+ fopimage.getWidth(),
+ fopimage.getHeight()
+ );
if (tiffImage.getStripCount() == 1) {
int comp = tiffImage.getCompression();
if (comp == 3) {
if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
return;
}
- io.setImageEncoding((byte) 0x81);
+ io.setImageEncoding((byte)0x81);
io.setImageData(fopimage.getRessourceBytes());
} else if (comp == 4) {
if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
return;
}
- io.setImageEncoding((byte) 0x82);
+ io.setImageEncoding((byte)0x82);
io.setImageData(fopimage.getRessourceBytes());
} else {
if (!fopimage.load(FopImage.BITMAP)) {
return;
}
- convertToGrayScaleImage(io, fopimage.getBitmaps(),
- fopimage.getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
} else {
if (!fopimage.load(FopImage.BITMAP)) {
return;
}
- convertToGrayScaleImage(io, fopimage.getBitmaps(), fopimage
- .getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
} else {
if (!fopimage.load(FopImage.BITMAP)) {
@@ -957,19 +1142,20 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
int y = mpts2units(pos.getY() + currentBPPosition);
int w = mpts2units(pos.getWidth());
int h = mpts2units(pos.getHeight());
- int res = getResolution();
- ImageObject io = afpDataStream.getImageObject(x, y, w, h, res,
- res);
+ ImageObject io = afpDataStream.getImageObject(x, y, w, h,
+ getResolution(), getResolution());
io.setImageParameters(
- (int) (fopimage.getHorizontalResolution() * 10),
- (int) (fopimage.getVerticalResolution() * 10), fopimage
- .getWidth(), fopimage.getHeight());
+ (int)(fopimage.getHorizontalResolution() * 10),
+ (int)(fopimage.getVerticalResolution() * 10),
+ fopimage.getWidth(),
+ fopimage.getHeight()
+ );
if (colorImages) {
- io.setImageIDESize((byte) 24);
+ io.setImageIDESize((byte)24);
io.setImageData(fopimage.getBitmaps());
} else {
- convertToGrayScaleImage(io, fopimage.getBitmaps(), fopimage
- .getWidth(), fopimage.getHeight(), this.bitsPerPixel);
+ convertToGrayScaleImage(io, fopimage.getBitmaps(),
+ fopimage.getWidth(), fopimage.getHeight());
}
}*/
}
@@ -983,7 +1169,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* @param out
* the OutputStream
* @throws IOException
- * In case of an I/O error.
+ * In case of an I/O error.
+ * @deprecated
+ * use ImageEncodingHelper.encodeRenderedImageAsRGB(image, out) directly instead
*/
public static void writeImage(RenderedImage image, OutputStream out)
throws IOException {
@@ -993,9 +1181,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Draws a BufferedImage to AFP.
*
+ * @param uri
+ * the uri of the image
* @param image
* the RenderedImage
- * @param imageResolution
+ * @param imageRes
* the resolution of the BufferedImage
* @param x
* the x coordinate (in mpt)
@@ -1006,55 +1196,67 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* @param h
* the height of the viewport (in mpt)
*/
- public void drawBufferedImage(RenderedImage image, int imageResolution, int x,
- int y, int w, int h) {
- int afpx = mpts2units(x);
- int afpy = mpts2units(y);
- int afpw = mpts2units(w);
- int afph = mpts2units(h);
- int afpres = getResolution();
+ public void drawBufferedImage(String uri, RenderedImage image, int imageRes, int x,
+ int y, int w, int h, Map foreignAttributes) {
+// int afpx = mpts2units(x);
+// int afpy = mpts2units(y);
+// int afpw = mpts2units(w);
+// int afph = mpts2units(h);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
try {
// Serialize image
//TODO Eventually, this should be changed not to buffer as this increases the
//memory consumption (see PostScript output)
- writeImage(image, baout);
- byte[] buf = baout.toByteArray();
-
- // Generate image
- ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
- afph, afpres, afpres);
- io.setImageParameters(imageResolution, imageResolution,
- image.getWidth(), image.getHeight());
- if (colorImages) {
- io.setImageIDESize((byte)24);
- io.setImageData(buf);
- } else {
- // TODO Teach it how to handle grayscale BufferedImages directly
- // because this is pretty inefficient
- convertToGrayScaleImage(io, buf,
- image.getWidth(), image.getHeight(), this.bitsPerPixel);
- }
+ ImageEncodingHelper.encodeRenderedImageAsRGB(image, baout);
} catch (IOException ioe) {
- log.error("Error while serializing bitmap: " + ioe.getMessage(),
- ioe);
+ log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
+ return;
}
+ //int res = getResolution();
+// String uri = null;// = image.getProperty(name);
+// String uri = image.getProperty(name);
+ // Generate image
+ ImageObjectParameters params = new ImageObjectParameters(
+ uri,
+ mpts2units(x), mpts2units(y),
+ mpts2units(w), mpts2units(h),
+ imageRes, imageRes,
+ baout.toByteArray(),
+ image.getWidth(),
+ image.getHeight(),
+ colorImages,
+ bitsPerPixel);
+
+ params.setResourceLevelFromForeignAttributes(foreignAttributes);
+ IncludeObject io = afpDataStream.createImageObject(params);
+// ImageObject io = afpDataStream.getImageObject(afpx, afpy, afpw,
+// afph, afpres, afpres);
+// io.setImageParameters(imageResolution, imageResolution,
+// image.getWidth(), image.getHeight());
+// if (colorImages) {
+// io.setImageIDESize((byte)24);
+// io.setImageData(buf);
+// } else {
+// // TODO Teach it how to handle grayscale BufferedImages directly
+// // because this is pretty inefficient
+// convertToGrayScaleImage(io, buf,
+// image.getWidth(), image.getHeight(), this.bitsPerPixel);
+// }
}
/**
- * Establishes a new foreground or fill color. {@inheritDoc}
+ * Establishes a new foreground or fill color.
+ * {@inheritDoc}
*/
public void updateColor(Color col, boolean fill) {
if (fill) {
- currentState.setColor(col);
+ currentColor = col;
}
}
/**
* Restores the state stack after a break out.
- *
- * @param breakOutList
- * the state stack to restore.
+ * @param breakOutList the state stack to restore.
*/
public void restoreStateStackAfterBreakOut(List breakOutList) {
@@ -1062,7 +1264,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Breaks out of the state stack to handle fixed block-containers.
- *
* @return the saved state stack to recreate later
*/
public List breakOutOfStateStack() {
@@ -1093,8 +1294,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* {@inheritDoc}
*/
public void renderImage(Image image, Rectangle2D pos) {
- String url = image.getURL();
- drawImage(url, pos);
+ drawImage(image.getURL(), pos, image.getForeignAttributes());
}
/**
@@ -1103,58 +1303,76 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
public void renderText(TextArea text) {
renderInlineAreaBackAndBorders(text);
- String internalFontName = getInternalFontNameForArea(text);
- this.currentState.setFontName(internalFontName);
- int currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
- this.currentState.setFontSize(currentFontSize);
- AFPFont font = (AFPFont) fontInfo.getFonts().get(internalFontName);
+ String name = getInternalFontNameForArea(text);
+ currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
+ AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
Color col = (Color) text.getTrait(Trait.COLOR);
- int vsci = mpts2units(font.getWidth(' ', currentFontSize) / 1000
- + text.getTextWordSpaceAdjust()
- + text.getTextLetterSpaceAdjust());
+ int vsci = mpts2units(tf.getWidth(' ', currentFontSize) / 1000
+ + text.getTextWordSpaceAdjust()
+ + text.getTextLetterSpaceAdjust());
// word.getOffset() = only height of text itself
// currentBlockIPPosition: 0 for beginning of line; nonzero
- // where previous line area failed to take up entire allocated space
+ // where previous line area failed to take up entire allocated space
int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
- int bl = currentBPPosition + text.getOffset()
- + text.getBaselineOffset();
+ int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
// Set letterSpacing
- // float ls = fs.getLetterSpacing() / this.currentFontSize;
+ //float ls = fs.getLetterSpacing() / this.currentFontSize;
String worddata = text.getText();
- AFPPageFonts pageFonts = this.currentState.getPageFonts();
- AFPFontAttributes afpFontAttributes = pageFonts.registerFont(
- internalFontName, font, currentFontSize);
+ // Create an AFPFontAttributes object from the current font details
+ AFPFontAttributes afpFontAttributes = new AFPFontAttributes(name, tf, currentFontSize);
+
+ if (!currentPageFonts.containsKey(afpFontAttributes.getFontKey())) {
+ // Font not found on current page, so add the new one
+ pageFontCounter++;
+ afpFontAttributes.setFontReference(pageFontCounter);
+ currentPageFonts.put(
+ afpFontAttributes.getFontKey(),
+ afpFontAttributes);
+
+ } else {
+ // Use the previously stored font attributes
+ afpFontAttributes = (AFPFontAttributes) currentPageFonts.get(
+ afpFontAttributes.getFontKey());
+ }
// Try and get the encoding to use for the font
String encoding = null;
try {
- encoding = font.getCharacterSet(currentFontSize).getEncoding();
+ encoding = tf.getCharacterSet(currentFontSize).getEncoding();
} catch (Throwable ex) {
encoding = AFPConstants.EBCIDIC_ENCODING;
- log.warn("renderText():: Error getting encoding for font "
- + " - using default encoding " + encoding);
+ log.warn(
+ "renderText():: Error getting encoding for font "
+ + " - using default encoding "
+ + encoding);
}
try {
- afpDataStream.createText(afpFontAttributes.getFontReference(),
- mpts2units(rx), pts2units(bl), col, vsci, mpts2units(text
- .getTextLetterSpaceAdjust()), worddata
- .getBytes(encoding));
+ afpDataStream.createText(
+ afpFontAttributes.getFontReference(),
+ mpts2units(rx),
+ mpts2units(bl),
+ col,
+ vsci,
+ mpts2units(text.getTextLetterSpaceAdjust()),
+ worddata.getBytes(encoding));
} catch (UnsupportedEncodingException usee) {
- log.error("renderText:: Font " + afpFontAttributes.getFontKey()
- + " caused UnsupportedEncodingException");
+ log.error(
+ "renderText:: Font "
+ + afpFontAttributes.getFontKey()
+ + " caused UnsupportedEncodingException");
}
super.renderText(text);
- renderTextDecoration(font, currentFontSize, text, bl, rx);
+ renderTextDecoration(tf, currentFontSize, text, bl, rx);
}
/**
@@ -1192,41 +1410,88 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
}
/**
- * Render leader area. This renders a leader area which is an area with a
- * rule.
- *
- * @param area
- * the leader area to render
+ * Render leader area.
+ * This renders a leader area which is an area with a rule.
+ * @param area the leader area to render
*/
public void renderLeader(Leader area) {
renderInlineAreaBackAndBorders(area);
int style = area.getRuleStyle();
- float startx = (currentIPPosition + area
- .getBorderAndPaddingWidthStart()) / 1000f;
+ float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
float starty = (currentBPPosition + area.getOffset()) / 1000f;
- float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart() + area
- .getIPD()) / 1000f;
+ float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart()
+ + area.getIPD()) / 1000f;
float ruleThickness = area.getRuleThickness() / 1000f;
- Color col = (Color) area.getTrait(Trait.COLOR);
+ Color col = (Color)area.getTrait(Trait.COLOR);
switch (style) {
- case EN_SOLID:
- case EN_DASHED:
- case EN_DOUBLE:
- case EN_DOTTED:
- case EN_GROOVE:
- case EN_RIDGE:
- drawBorderLine(startx, starty, endx, starty + ruleThickness, true,
- true, style, col);
- break;
- default:
- throw new UnsupportedOperationException("rule style not supported");
+ case EN_SOLID:
+ case EN_DASHED:
+ case EN_DOUBLE:
+ case EN_DOTTED:
+ case EN_GROOVE:
+ case EN_RIDGE:
+ drawBorderLine(startx, starty, endx, starty + ruleThickness,
+ true, true, style, col);
+ break;
+ default:
+ throw new UnsupportedOperationException("rule style not supported");
}
super.renderLeader(area);
}
/**
+ * Sets the AFPRenderer options
+ * @param options the <code>Map</code> containing the options
+ */
+// UNUSED
+// public void setOptions(Map options) {
+//
+// this.afpOptions = options;
+//
+// }
+ /**
+ * Determines the orientation from the string representation, this method
+ * guarantees to return a value of either 0, 90, 180 or 270.
+ *
+ * @return the orientation
+ */
+// UNUSED
+// private int getOrientation(String orientationString) {
+//
+// int orientation = 0;
+// if (orientationString != null && orientationString.length() > 0) {
+// try {
+// orientation = Integer.parseInt(orientationString);
+// } catch (NumberFormatException nfe) {
+// log.error("Cannot use orientation of " + orientation
+// + " defaulting to zero.");
+// orientation = 0;
+// }
+// } else {
+// orientation = 0;
+// }
+// switch (orientation) {
+// case 0:
+// break;
+// case 90:
+// break;
+// case 180:
+// break;
+// case 270:
+// break;
+// default:
+// log.error("Cannot use orientation of " + orientation
+// + " defaulting to zero.");
+// orientation = 0;
+// break;
+// }
+//
+// return orientation;
+//
+// }
+ /**
* Sets the rotation to be used for portrait pages, valid values are 0
* (default), 90, 180, 270.
*
@@ -1235,13 +1500,14 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
*/
public void setPortraitRotation(int rotation) {
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
+ if (rotation == 0
+ || rotation == 90
+ || rotation == 180
+ || rotation == 270) {
portraitRotation = rotation;
} else {
- throw new IllegalArgumentException(
- "The portrait rotation must be one"
- + " of the values 0, 90, 180, 270");
+ throw new IllegalArgumentException("The portrait rotation must be one"
+ + " of the values 0, 90, 180, 270");
}
@@ -1250,19 +1516,20 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Sets the rotation to be used for landsacpe pages, valid values are 0, 90,
* 180, 270 (default).
- *
+ *
* @param rotation
* The rotation in degrees.
*/
public void setLandscapeRotation(int rotation) {
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
+ if (rotation == 0
+ || rotation == 90
+ || rotation == 180
+ || rotation == 270) {
landscapeRotation = rotation;
} else {
- throw new IllegalArgumentException(
- "The landscape rotation must be one"
- + " of the values 0, 90, 180, 270");
+ throw new IllegalArgumentException("The landscape rotation must be one"
+ + " of the values 0, 90, 180, 270");
}
}
@@ -1270,7 +1537,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Get the MIME type of the renderer.
*
- * @return The MIME type of the renderer
+ * @return The MIME type of the renderer
*/
public String getMimeType() {
return MimeConstants.MIME_AFP;
@@ -1280,8 +1547,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* Method to render the page extension.
* <p>
*
- * @param pageViewport
- * the page object
+ * @param pageViewport the page object
*/
private void renderPageObjectExtensions(PageViewport pageViewport) {
@@ -1292,7 +1558,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
// the s-p-m
Iterator i = pageViewport.getExtensionAttachments().iterator();
while (i.hasNext()) {
- ExtensionAttachment attachment = (ExtensionAttachment) i.next();
+ ExtensionAttachment attachment = (ExtensionAttachment)i.next();
if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) {
AFPPageSetup aps = (AFPPageSetup) attachment;
String element = aps.getElementName();
@@ -1306,7 +1572,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
String name = aps.getName();
String source = aps.getValue();
if (pageSegmentsMap == null) {
- pageSegmentsMap = new HashMap();
+ pageSegmentsMap = new java.util.HashMap();
}
pageSegmentsMap.put(source, name);
} else if (AFPElementMapping.TAG_LOGICAL_ELEMENT
@@ -1314,7 +1580,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
String name = aps.getName();
String value = aps.getValue();
if (pageSegmentsMap == null) {
- pageSegmentsMap = new HashMap();
+ pageSegmentsMap = new java.util.HashMap();
}
afpDataStream.createTagLogicalElement(name, value);
} else if (AFPElementMapping.NO_OPERATION.equals(element)) {
@@ -1322,6 +1588,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
if (content != null) {
afpDataStream.createNoOperation(content);
}
+ } else if (AFPElementMapping.RESOURCE.equals(element)) {
+ System.out.println("resource: " + attachment);
}
}
}
@@ -1331,9 +1599,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Converts FOP mpt measurement to afp measurement units
- *
- * @param mpt
- * the millipoints value
+ * @param mpt the millipoints value
*/
private int mpts2units(int mpt) {
return mpts2units((double) mpt);
@@ -1341,9 +1607,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/**
* Converts FOP pt measurement to afp measurement units
- *
- * @param mpt
- * the millipoints value
+ * @param mpt the millipoints value
*/
private int pts2units(float mpt) {
return mpts2units(mpt * 1000d);
@@ -1357,8 +1621,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* @return afp measurement unit value
*/
private int mpts2units(double mpt) {
- return (int) Math
- .round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
+ return (int)Math.round(mpt / (DPI_CONVERSION_FACTOR / getResolution()));
}
/**
@@ -1422,7 +1685,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
io.setImageIDESize((byte) bitsPerPixel);
io.setImageData(bw);
}
-
+
private final class ViewPortPos {
private int x = 0;
@@ -1521,7 +1784,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
}
- private List viewPortPositions = new ArrayList();
+ private List viewPortPositions = new java.util.ArrayList();
private void pushViewPortPos(ViewPortPos vpp) {
viewPortPositions.add(vpp);
@@ -1531,8 +1794,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
private void popViewPortPos() {
viewPortPositions.remove(viewPortPositions.size() - 1);
if (viewPortPositions.size() > 0) {
- ViewPortPos vpp = (ViewPortPos) viewPortPositions
- .get(viewPortPositions.size() - 1);
+ ViewPortPos vpp = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
}
}
@@ -1546,9 +1808,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
public void setBitsPerPixel(int bitsPerPixel) {
this.bitsPerPixel = bitsPerPixel;
switch (bitsPerPixel) {
- case 1:
- case 4:
- case 8:
+ case 1:
+ case 4:
+ case 8:
break;
default:
log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
@@ -1573,6 +1835,9 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* @return the AFPDataStream
*/
public AFPDataStream getAFPDataStream() {
+ if (afpDataStream == null) {
+ this.afpDataStream = new AFPDataStream();
+ }
return afpDataStream;
}
@@ -1583,24 +1848,46 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* the output resolution (dpi)
*/
public void setResolution(int resolution) {
- if (resolution == DPI_240_RESOLUTION
- || resolution == DPI_1440_RESOLUTION) {
- this.resolution = resolution;
- if (log.isDebugEnabled()) {
- log.debug("renderer-resolution set to: " + resolution + " dpi");
- }
- } else {
- log.error("invalid resolution, can only be " + DPI_240_RESOLUTION
- + " or " + DPI_1440_RESOLUTION + " dpi");
+ if (log.isDebugEnabled()) {
+ log.debug("renderer-resolution set to: " + resolution + "dpi");
}
+ this.resolution = resolution;
}
-
+
/**
* Returns the output/device resolution.
- *
* @return the resolution in dpi
*/
public int getResolution() {
return this.resolution;
}
+
+ private AFPState getState() {
+ if (currentState == null) {
+ currentState = new AFPState();
+ }
+ return currentState;
+ }
+
+ private boolean gocaEnabled = false;
+
+ /**
+ * @param enabled true if AFP GOCA is enabled for SVG support
+ */
+ protected void setGOCAEnabled(boolean enabled) {
+ this.gocaEnabled = enabled;
+ }
+
+ /**
+ * @return true of AFP GOCA is enabled for SVG support
+ */
+ protected boolean isGOCAEnabled() {
+ return this.gocaEnabled;
+ }
+
+ /** {@inheritDoc} */
+ public void startPageSequence(LineArea seqTitle) {
+ afpDataStream.endPageGroup();
+ afpDataStream.startPageGroup();
+ }
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 9917eec70..4c8a3dc9f 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -140,18 +140,14 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
return new AFPFontInfo(font, tripleList);
} else if ("outline".equalsIgnoreCase(type)) {
-
String characterset = afpFontCfg.getAttribute("characterset");
if (characterset == null) {
log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
return null;
}
String name = afpFontCfg.getAttribute("name", characterset);
-
CharacterSet characterSet = null;
-
String base14 = afpFontCfg.getAttribute("base14-font", null);
-
if (base14 != null) {
try {
Class clazz = Class.forName("org.apache.fop.fonts.base14."
@@ -205,7 +201,6 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
+ triplet.getWeight());
}
}
-
fontList.add(afi);
}
}
@@ -242,6 +237,31 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
afpRenderer.setResolution(rendererResolutionCfg.getValueAsInteger(
AFPRenderer.DPI_240_RESOLUTION));
}
+
+ Configuration gocaSupportCfg = cfg.getChild("goca-enabled", false);
+ if (gocaSupportCfg != null) {
+ afpRenderer.setGOCAEnabled(true);
+ }
+
+// Configuration resourceGroupsCfg = cfg.getChild("resource-groups", false);
+// if (resourceGroupsCfg != null) {
+// resourceGroupsCfg.getValue("print-file-level");
+// }
+// if (externalCfg != null) {
+// Configuration[] resourceGroups = externalCfg.getChildren("resource-groups");
+// for (int i = 0; i < resourceGroups.length; i++) {
+// String resourceresourceGroups[i].getAttribute("url", null);
+// Configuration resourceGroup = externalCfg.getChild("resource-group", false);
+// }
+// }
+// Configuration externalResourceGroupCfg = cfg.getChild("external-resource-group", false);
+// if (externalResourceGroupCfg != null) {
+//// afpRenderer.setExternalResources(true);
+// String resourceLibraryUrl = externalResourceGroupCfg.getAttribute("url", null);
+// if (resourceLibraryUrl != null) {
+// afpRenderer.setExternalResourceLibraryUrl(resourceLibraryUrl);
+// }
+// }
}
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
index 13fa62514..2641e6fbe 100644
--- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
@@ -22,10 +22,12 @@ package org.apache.fop.render.afp;
// FOP
import java.awt.geom.AffineTransform;
import java.io.IOException;
+import java.util.Map;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.commons.logging.Log;
@@ -33,7 +35,10 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContextConstants;
import org.apache.fop.render.afp.modca.AFPDataStream;
+import org.apache.fop.render.afp.modca.GraphicsObject;
+import org.apache.fop.render.afp.modca.IncludeObject;
import org.apache.fop.svg.SVGUserAgent;
import org.w3c.dom.Document;
@@ -65,28 +70,29 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
*/
public static AFPInfo getAFPInfo(RendererContext context) {
AFPInfo afpi = new AFPInfo();
- afpi.width = ((Integer)context.getProperty(WIDTH)).intValue();
- afpi.height = ((Integer)context.getProperty(HEIGHT)).intValue();
- afpi.currentXPosition = ((Integer)context.getProperty(XPOS)).intValue();
- afpi.currentYPosition = ((Integer)context.getProperty(YPOS)).intValue();
- afpi.cfg = (Configuration)context.getProperty(HANDLER_CONFIGURATION);
- afpi.fontInfo = (org.apache.fop.fonts.FontInfo)context.getProperty(
- AFPRendererContextConstants.AFP_FONT_INFO);
- afpi.resolution = ((Integer)context.getProperty(
- AFPRendererContextConstants.AFP_RESOLUTION)).intValue();
- afpi.afpState = (AFPState)context.getProperty(
- AFPRendererContextConstants.AFP_STATE);
- afpi.afpDataStream = (AFPDataStream)context.getProperty(
- AFPRendererContextConstants.AFP_DATASTREAM);
- afpi.grayscale = ((Boolean)context.getProperty(
- AFPRendererContextConstants.AFP_GRAYSCALE)).booleanValue();
- afpi.bitsPerPixel = ((Integer)context.getProperty(
- AFPRendererContextConstants.AFP_BITS_PER_PIXEL)).intValue();
+ afpi.setWidth(((Integer)context.getProperty(WIDTH)).intValue());
+ afpi.setHeight(((Integer)context.getProperty(HEIGHT)).intValue());
+ afpi.setX(((Integer)context.getProperty(XPOS)).intValue());
+ afpi.setY(((Integer)context.getProperty(YPOS)).intValue());
+ afpi.setHandlerConfiguration((Configuration)context.getProperty(HANDLER_CONFIGURATION));
+ afpi.setFontInfo((org.apache.fop.fonts.FontInfo)context.getProperty(
+ AFPRendererContextConstants.AFP_FONT_INFO));
+ afpi.setResolution(((Integer)context.getProperty(
+ AFPRendererContextConstants.AFP_RESOLUTION)).intValue());
+ afpi.setState((AFPState)context.getProperty(
+ AFPRendererContextConstants.AFP_STATE));
+ afpi.setAFPDataStream((AFPDataStream)context.getProperty(
+ AFPRendererContextConstants.AFP_DATASTREAM));
+ afpi.setColor(!((Boolean)context.getProperty(
+ AFPRendererContextConstants.AFP_GRAYSCALE)).booleanValue());
+ afpi.setBitsPerPixel(((Integer)context.getProperty(
+ AFPRendererContextConstants.AFP_BITS_PER_PIXEL)).intValue());
return afpi;
}
/**
* Render the SVG document.
+ *
* @param context the renderer context
* @param doc the SVG document
* @param afpInfo the AFPInfo renderer parameters
@@ -100,14 +106,16 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
graphics.setAFPInfo(afpInfo);
+ String uri = ((AbstractDocument)doc).getDocumentURI();
+ graphics.setDocumentURI(uri);
+
GVTBuilder builder = new GVTBuilder();
boolean strokeText = false;
- Configuration cfg = afpInfo.cfg;
+ Configuration cfg = afpInfo.getHandlerConfiguration();
if (cfg != null) {
strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
}
-
final float uaResolution = context.getUserAgent().getSourceResolution();
SVGUserAgent svgUserAgent = new SVGUserAgent(25.4f / uaResolution, new AffineTransform());
@@ -122,7 +130,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
AFPTextElementBridge tBridge = new AFPTextElementBridge(textPainter);
ctx.putBridge(tBridge);
}
-
+
GraphicsNode root;
try {
root = builder.build(ctx, doc);
@@ -132,33 +140,59 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
return;
}
log.debug("Generating SVG at "
- + afpInfo.resolution + "dpi.");
+ + afpInfo.getResolution() + "dpi.");
- int res = afpInfo.resolution;
-
+ int res = afpInfo.getResolution();
double w = ctx.getDocumentSize().getWidth() * 1000f;
double h = ctx.getDocumentSize().getHeight() * 1000f;
// convert to afp inches
- double sx = ((afpInfo.width / w) * res) / 72f;
- double sy = ((afpInfo.height / h) * res) / 72f;
- double xOffset = (afpInfo.currentXPosition * res) / 72000f;
- double yOffset = ((afpInfo.height - afpInfo.currentYPosition) * res) / 72000f;
+ double sx = ((afpInfo.getWidth() / w) * res) / 72f;
+ double sy = ((afpInfo.getHeight() / h) * res) / 72f;
+ double xOffset = (afpInfo.getX() * res) / 72000f;
+ double yOffset = ((afpInfo.getHeight() - afpInfo.getY()) * res) / 72000f;
// Transformation matrix that establishes the local coordinate system for the SVG graphic
// in relation to the current coordinate system (note: y axis is inverted)
AffineTransform trans = new AffineTransform(sx, 0, 0, -sy, xOffset, yOffset);
graphics.setTransform(trans);
+
+ int x = (int)Math.round((afpInfo.getX() * 25.4f) / 1000);
+ int y = (int)Math.round((afpInfo.getY() * 25.4f) / 1000);
+ int width = (int)Math.round((afpInfo.getWidth() * res) / 72000f);
+ int height = (int)Math.round((afpInfo.getHeight() * res) / 72000f);
+
+ DataObjectParameters params = new DataObjectParameters(
+ uri, x, y, width, height, res, res);
+
+ Map/*<QName, String>*/ foreignAttributes
+ = (Map/*<QName, String>*/)context.getProperty(
+ RendererContextConstants.FOREIGN_ATTRIBUTES);
+
+ if (foreignAttributes != null) {
+ params.setResourceLevelFromForeignAttributes(foreignAttributes);
+ }
+
+ IncludeObject includeObj = afpInfo.getAFPDataStream().createGraphicsObject(params);
+ GraphicsObject graphicsObj = (GraphicsObject)includeObj.getReferencedObject();
+ graphics.setGraphicsObject(graphicsObj);
+
try {
root.paint(graphics);
} catch (Exception e) {
log.error("SVG graphic could not be rendered: " + e.getMessage(), e);
}
+
+ graphics.dispose();
}
/** {@inheritDoc} */
public boolean supportsRenderer(Renderer renderer) {
- return (renderer instanceof AFPRenderer);
+ if (renderer instanceof AFPRenderer) {
+ AFPRenderer afpRenderer = (AFPRenderer)renderer;
+ return afpRenderer.isGOCAEnabled();
+ }
+ return false;
}
/** {@inheritDoc} */
@@ -166,4 +200,3 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
return SVGDOMImplementation.SVG_NAMESPACE_URI;
}
}
-
diff --git a/src/java/org/apache/fop/render/afp/AFPState.java b/src/java/org/apache/fop/render/afp/AFPState.java
index 7cb37e2f3..5977d0de2 100644
--- a/src/java/org/apache/fop/render/afp/AFPState.java
+++ b/src/java/org/apache/fop/render/afp/AFPState.java
@@ -20,51 +20,18 @@
package org.apache.fop.render.afp;
import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.io.Serializable;
import java.util.Arrays;
+import java.util.List;
/**
* This keeps information about the current state when writing to pdf.
*/
public class AFPState {
- /**
- * The current color
- */
- private Color color = null;
-
- /**
- * The current background color
- */
- private Color backColor = null;
-
- /**
- * The current font name
- */
- private String fontName = null;
-
- /**
- * The current font size
- */
- private int fontSize = 0;
-
- /**
- * The current line width
- */
- private float lineWidth = 0;
-
- /**
- * The dash array for the current basic stroke (line type)
- */
- private float[] dashArray = null;
-
- /**
- * The current fill status
- */
- private boolean filled = false;
+ private Data data = new Data();
- /**
- * The fonts on the current page
- */
- private AFPPageFonts pageFonts = null;
+ private List stateStack = new java.util.ArrayList();
/**
* Set the current color.
@@ -74,8 +41,8 @@ public class AFPState {
* @return true if the color has changed
*/
protected boolean setColor(Color col) {
- if (!col.equals(this.color)) {
- this.color = col;
+ if (!col.equals(getData().color)) {
+ getData().color = col;
return true;
}
return false;
@@ -87,8 +54,8 @@ public class AFPState {
* @return true if the fill value has changed
*/
protected boolean setFill(boolean fill) {
- if (fill != this.filled) {
- this.filled = fill;
+ if (fill != getData().filled) {
+ getData().filled = fill;
return true;
}
return false;
@@ -99,10 +66,10 @@ public class AFPState {
* @return the color
*/
protected Color getColor() {
- if (this.color == null) {
- this.color = Color.black;
+ if (getData().color == null) {
+ getData().color = Color.black;
}
- return this.color;
+ return getData().color;
}
/**
@@ -111,8 +78,8 @@ public class AFPState {
* @return true if the line width has changed
*/
protected boolean setLineWidth(float width) {
- if (this.lineWidth != width) {
- this.lineWidth = width;
+ if (getData().lineWidth != width) {
+ getData().lineWidth = width;
return true;
}
return false;
@@ -124,8 +91,8 @@ public class AFPState {
* @return true if the dash array has changed
*/
public boolean setDashArray(float[] dash) {
- if (!Arrays.equals(dash, this.dashArray)) {
- this.dashArray = dash;
+ if (!Arrays.equals(dash, getData().dashArray)) {
+ getData().dashArray = dash;
return true;
}
return false;
@@ -136,7 +103,7 @@ public class AFPState {
* @return the current line width
*/
protected float getLineWidth() {
- return lineWidth;
+ return getData().lineWidth;
}
/**
@@ -144,10 +111,10 @@ public class AFPState {
* @return the background color
*/
protected Color getBackColor() {
- if (this.backColor == null) {
- this.backColor = Color.white;
+ if (getData().backColor == null) {
+ getData().backColor = Color.white;
}
- return backColor;
+ return getData().backColor;
}
/**
@@ -158,8 +125,8 @@ public class AFPState {
* @return true if the color has changed
*/
protected boolean setBackColor(Color col) {
- if (!col.equals(this.backColor)) {
- this.backColor = col;
+ if (!col.equals(getData().backColor)) {
+ getData().backColor = col;
return true;
}
return false;
@@ -171,8 +138,8 @@ public class AFPState {
* @return true if the font name has changed
*/
protected boolean setFontName(String internalFontName) {
- if (!internalFontName.equals(this.fontName)) {
- this.fontName = internalFontName;
+ if (!internalFontName.equals(getData().fontName)) {
+ getData().fontName = internalFontName;
return true;
}
return false;
@@ -183,7 +150,7 @@ public class AFPState {
* @return the current font name
*/
protected String getFontName() {
- return this.fontName;
+ return getData().fontName;
}
/**
@@ -191,7 +158,7 @@ public class AFPState {
* @return the current font size
*/
protected int getFontSize() {
- return this.fontSize;
+ return getData().fontSize;
}
/**
@@ -202,8 +169,8 @@ public class AFPState {
* @return true if the font size has changed
*/
protected boolean setFontSize(int size) {
- if (size != this.fontSize) {
- this.fontSize = size;
+ if (size != getData().fontSize) {
+ getData().fontSize = size;
return true;
}
return false;
@@ -214,25 +181,98 @@ public class AFPState {
* @return the current page fonts
*/
protected AFPPageFonts getPageFonts() {
- if (this.pageFonts == null) {
- this.pageFonts = new AFPPageFonts();
+ if (getData().pageFonts == null) {
+ getData().pageFonts = new AFPPageFonts();
}
- return this.pageFonts;
- }
-
- /**
- * Resets the current state
- */
- protected void reset() {
- this.color = null;
- this.backColor = null;
- this.fontName = null;
- this.fontSize = 0;
- this.lineWidth = 0;
- this.dashArray = null;
- this.filled = false;
- if (this.pageFonts != null) {
- this.pageFonts.clear();
+ return getData().pageFonts;
+ }
+
+ /**
+ * Push the current 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() {
+ Data copy;
+ try {
+ copy = (Data)getData().clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ stateStack.add(copy);
+ }
+
+ /**
+ * Get the current stack level.
+ *
+ * @return the current stack level
+ */
+ public int getStackLevel() {
+ return stateStack.size();
+ }
+
+ /**
+ * Pop the state from the stack and set current values to popped state.
+ * This should be called when a Q operator is used so
+ * the state is restored to the correct values.
+ * @return the restored state, null if the stack is empty
+ */
+ public Data pop() {
+ if (getStackLevel() > 0) {
+ Data popped = (Data)stateStack.remove(stateStack.size() - 1);
+ data = popped;
+ return popped;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @return the currently valid state
+ */
+ public Data getData() {
+ return data;
+ }
+
+ public class Data implements Cloneable, Serializable {
+ private static final long serialVersionUID = -1789481244175275686L;
+
+ /** The current color */
+ private Color color = null;
+
+ /** The current background color */
+ private Color backColor = null;
+
+ /** The current font name */
+ private String fontName = null;
+
+ /** The current font size */
+ private int fontSize = 0;
+
+ /** The current line width */
+ private float lineWidth = 0;
+
+ /** The dash array for the current basic stroke (line type) */
+ private float[] dashArray = null;
+
+ /** The current fill status */
+ private boolean filled = false;
+
+ /** The fonts on the current page */
+ private AFPPageFonts pageFonts = null;
+
+ /** {@inheritDoc} */
+ public Object clone() throws CloneNotSupportedException {
+ Data obj = new Data();
+ obj.color = this.color;
+ obj.backColor = this.backColor;
+ obj.fontName = this.fontName;
+ obj.fontSize = this.fontSize;
+ obj.lineWidth = this.lineWidth;
+ obj.dashArray = this.dashArray;
+ obj.filled = this.filled;
+ obj.pageFonts = this.pageFonts;
+ return obj;
}
}
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/DataObjectParameters.java b/src/java/org/apache/fop/render/afp/DataObjectParameters.java
new file mode 100644
index 000000000..2ec56a4e3
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/DataObjectParameters.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.extensions.AFPElementMapping;
+import org.apache.fop.util.QName;
+
+/**
+ * A list of parameters associated with an AFP data objects
+ */
+public class DataObjectParameters {
+ private static final ResourceLevel DEFAULT_RESOURCE_LEVEL = new ResourceLevel();
+
+ private String uri;
+ private int x;
+ private int y;
+ private int width;
+ private int height;
+ private int widthRes;
+ private int heightRes;
+ private ResourceLevel resourceLevel = DEFAULT_RESOURCE_LEVEL;
+
+ /**
+ * Main constructor
+ *
+ * @param uri the data object uri
+ * @param x the data object x coordinate
+ * @param y the data object y coordinate
+ * @param width the data object width
+ * @param height the data object height
+ * @param widthRes the data object width resolution
+ * @param heightRes the data object height resolution
+ */
+ public DataObjectParameters(String uri, int x, int y, int width, int height,
+ int widthRes, int heightRes) {
+ this.uri = uri;
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.widthRes = widthRes;
+ this.heightRes = heightRes;
+ }
+
+ /**
+ * @return the uri of this data object
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * @return the x coordinate of this data object
+ */
+ public int getX() {
+ return x;
+ }
+
+ /**
+ * @return the y coordinate of this data object
+ */
+ public int getY() {
+ return y;
+ }
+
+ /**
+ * @return the width of this data object
+ */
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * @return the height of this data object
+ */
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * @return the width resolution of this data object
+ */
+ public int getWidthRes() {
+ return widthRes;
+ }
+
+ /**
+ * @return the height resolution of this data object
+ */
+ public int getHeightRes() {
+ return heightRes;
+ }
+
+ /**
+ * @return returns the resource level at which this data object should reside
+ */
+ public ResourceLevel getResourceLevel() {
+ return resourceLevel;
+ }
+
+ /**
+ * Sets the resource level at which this object should reside
+ * @param resourceLevel the resource level at which this data object should reside
+ */
+ public void setResourceLevel(ResourceLevel resourceLevel) {
+ this.resourceLevel = resourceLevel;
+ }
+
+ /**
+ * Sets the resource level using the given foreign attributes
+ * @param foreignAttributes a mapping of element attributes names to values
+ */
+ public void setResourceLevelFromForeignAttributes(Map/*<QName, String>*/ foreignAttributes) {
+ if (foreignAttributes != null) {
+ QName resourceLevelKey = new QName(
+ AFPElementMapping.NAMESPACE,
+ "afp:resource-level");
+ if (foreignAttributes.containsKey(resourceLevelKey)) {
+ String level = (String)foreignAttributes.get(resourceLevelKey);
+ this.resourceLevel = new ResourceLevel();
+ if (resourceLevel.setLevel(level)) {
+ if (resourceLevel.isExternal()) {
+ QName resourceDestKey = new QName(
+ AFPElementMapping.NAMESPACE,
+ "afp:resource-dest");
+ String resourceExternalDest
+ = (String)foreignAttributes.get(resourceDestKey);
+ resourceLevel.setExternalDest(resourceExternalDest);
+ }
+ } else {
+ Log log = LogFactory.getLog("org.apache.fop.afp");
+ log.warn("invalid resource level '" + level
+ + "', using default document level");
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "uri=" + uri
+ + ", x=" + x
+ + ", y=" + y
+ + ", width=" + width
+ + ", height=" + height
+ + ", widthRes=" + widthRes
+ + ", heightRes=" + heightRes
+ + (resourceLevel != null ? ", resourceLevel=" + resourceLevel : "");
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/ImageObjectParameters.java b/src/java/org/apache/fop/render/afp/ImageObjectParameters.java
new file mode 100644
index 000000000..8b430f042
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/ImageObjectParameters.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp;
+
+/**
+ * A list of parameters associated with an image
+ */
+public class ImageObjectParameters extends DataObjectParameters {
+ private int bitsPerPixel;
+ private boolean color;
+ private int compression = -1;
+ private byte[] imageData;
+ private int imageDataWidth;
+ private int imageDataHeight;
+
+ /**
+ * Main constructor
+ *
+ * @param uri the image uri
+ * @param x the image x coordinate
+ * @param y the image y coordinate
+ * @param width the image width
+ * @param height the image height
+ * @param widthRes the image width resolution
+ * @param heightRes the image height resolution
+ */
+ public ImageObjectParameters(String uri, int x, int y, int width, int height,
+ int widthRes, int heightRes, byte[] imageData,
+ int imageDataWidth, int imageDataHeight, boolean color, int bitsPerPixel) {
+ super(uri, x, y, width, height, widthRes, heightRes);
+ this.imageData = imageData;
+ this.imageDataWidth = imageDataWidth;
+ this.imageDataHeight = imageDataHeight;
+ this.color = color;
+ this.bitsPerPixel = bitsPerPixel;
+ }
+
+ /**
+ * @return the numner of bits used per pixel
+ */
+ public int getBitsPerPixel() {
+ return bitsPerPixel;
+ }
+
+ /**
+ * @return true if this is a color image
+ */
+ public boolean isColor() {
+ return color;
+ }
+
+ /**
+ * @return the image data
+ */
+ public byte[] getData() {
+ return imageData;
+ }
+
+ /**
+ * @return true of this image uses compression
+ */
+ public boolean hasCompression() {
+ return compression > -1;
+ }
+
+ /**
+ * @return the compression type
+ */
+ public int getCompression() {
+ return compression;
+ }
+
+ /**
+ * Sets the compression used with this image
+ * @param compression the type of compression used with this image
+ */
+ public void setCompression(int compression) {
+ this.compression = compression;
+ }
+
+ /**
+ * @return the image data width
+ */
+ public int getImageDataWidth() {
+ return imageDataWidth;
+ }
+
+ /**
+ * Sets the image data width
+ * @param imageDataWidth the image data width
+ */
+ protected void setImageDataWidth(int imageDataWidth) {
+ this.imageDataWidth = imageDataWidth;
+ }
+
+ /**
+ * @return the image data height
+ */
+ public int getImageDataHeight() {
+ return imageDataHeight;
+ }
+
+ /**
+ * Sets the image data height
+ * @param imageDataHeight the image data height
+ */
+ protected void setImageDataHeight(int imageDataHeight) {
+ this.imageDataHeight = imageDataHeight;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return super.toString()
+ + ", imageDataWidth=" + imageDataWidth
+ + ", imageDataHeight=" + imageDataHeight
+ + ", color=" + color
+ + ", bitPerPixel=" + bitsPerPixel;
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/ResourceLevel.java b/src/java/org/apache/fop/render/afp/ResourceLevel.java
new file mode 100644
index 000000000..f397edb04
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/ResourceLevel.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp;
+
+/**
+ * The level at which a resource is to reside in the AFP output
+ */
+public class ResourceLevel {
+ private static final String EXTERNAL = "external";
+
+ private static final String PRINT_FILE = "print-file";
+
+ private static final String DOCUMENT = "document";
+
+ private static final String PAGE_GROUP = "page-group";
+
+ private static final String PAGE = "page";
+
+ /**
+ * where the resource will reside in the AFP output
+ */
+ private String level = PAGE; // default is page level
+
+ /**
+ * the destination location of the resource
+ */
+ private String dest = null;
+
+ /**
+ * @return true if this is a page level resource group
+ */
+ public boolean isPage() {
+ return level.equals(PAGE);
+ }
+
+ /**
+ * @return true if this is a page group level resource group
+ */
+ public boolean isPageGroup() {
+ return level.equals(PAGE_GROUP);
+ }
+
+ /**
+ * @return true if this is a document level resource group
+ */
+ public boolean isDocument() {
+ return level.equals(DOCUMENT);
+ }
+
+ /**
+ * @return true if this is an external level resource group
+ */
+ public boolean isExternal() {
+ return level.equals(EXTERNAL);
+ }
+
+ /**
+ * @return true if this is a print-file level resource group
+ */
+ public boolean isPrintFile() {
+ return level.equals(PRINT_FILE);
+ }
+
+ private boolean isValid(String lvl) {
+ return lvl.equals(EXTERNAL)
+ || lvl.equals(PRINT_FILE)
+ || lvl.equals(DOCUMENT)
+ || lvl.equals(PAGE_GROUP)
+ || lvl.equals(PAGE);
+ }
+
+ /**
+ * Sets the resource placement level within the AFP output
+ * @param level the resource level (page, page-group, document, print-file or external)
+ * @return true if the resource level was successfully set
+ */
+ public boolean setLevel(String level) {
+ if (isValid(level)) {
+ this.level = level;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @return the external destination of the resource
+ */
+ public String getExternalDest() {
+ return dest;
+ }
+
+ /**
+ * Sets the external destination of the resource
+ * @param dest the external destination of the resource
+ */
+ public void setExternalDest(String dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "level=" + level + (isExternal() ? ", dest=" + dest : "");
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java b/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java
index 665a77562..6b4bc4eb9 100755
--- a/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPAttribute.java
@@ -19,14 +19,13 @@
package org.apache.fop.render.afp.extensions;
-import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.StringProperty;
/**
* This class extends the org.apache.fop.fo.StringProperty.Maker inner class
- * in order to provide a static property maker. The object faciliates
+ * in order to provide a static property maker. The object facilitates
* extraction of attributes from formatted objects based on the static list
* as defined in the AFPElementMapping implementation.
* <p/>
@@ -58,5 +57,4 @@ public class AFPAttribute extends StringProperty.Maker {
}
return property;
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPElement.java
index b8bfa74b6..808cd88f1 100755
--- a/src/java/org/apache/fop/render/afp/extensions/AFPElement.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPElement.java
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
/**
* This class extends the org.apache.fop.extensions.ExtensionObj class. The
@@ -54,4 +55,7 @@ public class AFPElement extends AbstractAFPExtensionObject {
}
}
+ protected ExtensionAttachment instantiateExtensionAttachment() {
+ return null;
+ }
}
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java
index 216379cc0..8d4b0ae5e 100755
--- a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java
@@ -50,6 +50,9 @@ public class AFPElementMapping extends ElementMapping {
/** include page segment element */
public static final String INCLUDE_PAGE_SEGMENT = "include-page-segment";
+ /** include resource element (external) */
+ public static final String RESOURCE = "resource";
+
/** NOP */
public static final String NO_OPERATION = "no-operation";
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java
new file mode 100644
index 000000000..9a8429b00
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionAttachment.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.extensions;
+
+import java.io.Serializable;
+
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.xmlgraphics.util.XMLizable;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This is the pass-through value object for the AFP extension.
+ */
+public abstract class AFPExtensionAttachment
+ implements ExtensionAttachment, Serializable, XMLizable {
+ private static final long serialVersionUID = 7190606822558332901L;
+
+ /** The category URI for this extension attachment. */
+ public static final String CATEGORY = "apache:fop:extensions:afp";
+
+ /**
+ * the extension element name
+ */
+ protected String elementName;
+
+ /**
+ * the extension content
+ */
+ protected String content;
+
+ /**
+ * the extension name attribute
+ */
+ protected String name;
+
+ /**
+ * the extension value attribute
+ */
+ protected String value;
+
+ /**
+ * Default constructor.
+ *
+ * @param elementName the name of the afp extension attachment, may be null
+ */
+ public AFPExtensionAttachment(String elementName) {
+ this.elementName = elementName;
+ }
+
+ /** @return the name */
+ public String getElementName() {
+ return elementName;
+ }
+
+ /**
+ * @return true if this element has a name attribute
+ */
+ protected boolean hasName() {
+ return name != null;
+ }
+
+ /** @return the name */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the setup code object.
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value
+ * @param source The value name to set.
+ */
+ public void setValue(String source) {
+ this.value = source;
+ }
+
+ /** {@inheritDoc} */
+ public String getCategory() {
+ return CATEGORY;
+ }
+
+ /**
+ * @return the data
+ */
+ public String getContent() {
+ return content;
+ }
+
+ /**
+ * Sets the data
+ * @param content The byte data to set.
+ */
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ /**
+ * name attribute
+ */
+ protected static final String ATT_NAME = "name";
+
+ /**
+ * value attribute
+ */
+ protected static final String ATT_VALUE = "value";
+
+ /** {@inheritDoc} */
+ public void toSAX(ContentHandler handler) throws SAXException {
+ AttributesImpl atts = new AttributesImpl();
+ if (name != null && name.length() > 0) {
+ atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name);
+ }
+ if (value != null && value.length() > 0) {
+ atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value);
+ }
+ handler.startElement(CATEGORY, elementName, elementName, atts);
+ if (content != null && content.length() > 0) {
+ char[] chars = content.toCharArray();
+ handler.characters(chars, 0, chars.length);
+ }
+ handler.endElement(CATEGORY, elementName, elementName);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java
index 7fdf7cd11..72d7639bd 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java
@@ -54,7 +54,9 @@ public class AFPExtensionHandler extends DefaultHandler
|| localName.equals(AFPElementMapping.INCLUDE_PAGE_OVERLAY)
|| localName.equals(AFPElementMapping.INCLUDE_PAGE_SEGMENT)
|| localName.equals(AFPElementMapping.PAGE)
- || localName.equals(AFPElementMapping.PAGE_GROUP)) {
+ || localName.equals(AFPElementMapping.PAGE_GROUP)
+ || localName.equals(AFPElementMapping.PAGE_GROUP)
+ || localName.equals(AFPResource.ELEMENT)) {
//handled in endElement
} else {
handled = false;
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java
index 91ab2dfa5..437222daa 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetup.java
@@ -19,33 +19,10 @@
package org.apache.fop.render.afp.extensions;
-import java.io.Serializable;
-
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import org.apache.xmlgraphics.util.XMLizable;
-
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-
/**
* This is the pass-through value object for the PostScript extension.
*/
-public class AFPPageSetup implements ExtensionAttachment, Serializable, XMLizable {
-
- private static final long serialVersionUID = 7190606822558332901L;
-
- /** The category URI for this extension attachment. */
- public static final String CATEGORY = "apache:fop:extensions:afp";
-
- private String elementName;
-
- private String name;
-
- private String value;
-
- private String content;
+public class AFPPageSetup extends AFPExtensionAttachment {
/**
* Default constructor.
@@ -53,85 +30,16 @@ public class AFPPageSetup implements ExtensionAttachment, Serializable, XMLizabl
* @param elementName the name of the setup code object, may be null
*/
public AFPPageSetup(String elementName) {
- this.elementName = elementName;
+ super(elementName);
}
- /** @return the name */
- public String getElementName() {
- return elementName;
- }
-
- /** @return the name */
- public String getName() {
- return name;
- }
+ private static final long serialVersionUID = -549941295384013190L;
/**
- * Sets the name of the setup code object.
- * @param name The name to set.
+ * {@inheritDoc}
*/
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @return the value
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Sets the value
- * @param source The value name to set.
- */
- public void setValue(String source) {
- this.value = source;
- }
-
- /** {@inheritDoc} */
- public String getCategory() {
- return CATEGORY;
- }
-
- /**
- * @return the data
- */
- public String getContent() {
- return content;
- }
-
- /**
- * Sets the data
- * @param content The byte data to set.
- */
- public void setContent(String content) {
- this.content = content;
- }
-
- /** {@inheritDoc} */
public String toString() {
return "AFPPageSetup(element-name=" + getElementName()
+ " name=" + getName() + " value=" + getValue() + ")";
}
-
- private static final String ATT_NAME = "name";
- private static final String ATT_VALUE = "value";
-
- /** {@inheritDoc} */
- public void toSAX(ContentHandler handler) throws SAXException {
- AttributesImpl atts = new AttributesImpl();
- if (name != null && name.length() > 0) {
- atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name);
- }
- if (value != null && value.length() > 0) {
- atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value);
- }
- handler.startElement(CATEGORY, elementName, elementName, atts);
- if (content != null && content.length() > 0) {
- char[] chars = content.toCharArray();
- handler.characters(chars, 0, chars.length);
- }
- handler.endElement(CATEGORY, elementName, elementName);
- }
}
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java
index 4971928f8..d167a8d4b 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java
@@ -23,9 +23,10 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
/**
- * Extension element for fox:ps-page-setup-code.
+ * Extension element for afp:ps-page-setup-code.
*/
public class AFPPageSetupElement extends AbstractAFPExtensionObject {
@@ -45,4 +46,10 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject {
}
}
+ /**
+ * {@inheritDoc}
+ */
+ protected ExtensionAttachment instantiateExtensionAttachment() {
+ return new AFPPageSetup(this.name);
+ }
}
diff --git a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java
index e641d2df8..ff6d56785 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AbstractAFPExtensionObject.java
@@ -34,11 +34,14 @@ import org.xml.sax.Locator;
public abstract class AbstractAFPExtensionObject extends FONode {
/**
- * AFP setup code
+ * the AFP extension attachment
*/
- private AFPPageSetup setupCode;
+ protected AFPExtensionAttachment extensionAttachment;
- private String name;
+ /**
+ * the element name of this extension
+ */
+ protected String name;
/**
* @see org.apache.fop.fo.FONode#FONode(FONode)
@@ -48,10 +51,11 @@ public abstract class AbstractAFPExtensionObject extends FONode {
public AbstractAFPExtensionObject(FONode parent, String name) {
super(parent);
this.name = name;
- this.setupCode = new AFPPageSetup(name);
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
@@ -59,60 +63,85 @@ public abstract class AbstractAFPExtensionObject extends FONode {
}
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
protected void addCharacters(char[] data, int start, int end,
- PropertyList pList, Locator locator) {
- setupCode.setContent(new String(data, start, end - start));
+ PropertyList pList, Locator locator) throws FOPException {
+ ((AFPExtensionAttachment)getExtensionAttachment()).setContent(
+ new String(data, start, end - start));
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public String getNamespaceURI() {
return AFPElementMapping.NAMESPACE;
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public String getNormalNamespacePrefix() {
return AFPElementMapping.NAMESPACE_PREFIX;
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void processNode(String elementName, Locator locator,
Attributes attlist, PropertyList propertyList)
throws FOPException {
- String name = attlist.getValue("name");
- if (name != null && name.length() > 0) {
- setupCode.setName(name);
+ getExtensionAttachment();
+ String attr = attlist.getValue("name");
+ if (attr != null && attr.length() > 0) {
+ extensionAttachment.setName(attr);
} else {
throw new FOPException(elementName + " must have a name attribute.");
}
if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) {
- name = attlist.getValue("src");
- if (name != null && name.length() > 0) {
- setupCode.setValue(name);
+ attr = attlist.getValue("src");
+ if (attr != null && attr.length() > 0) {
+ extensionAttachment.setValue(attr);
} else {
throw new FOPException(elementName + " must have a src attribute.");
}
} else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) {
- name = attlist.getValue("value");
- if (name != null && name.length() > 0) {
- setupCode.setValue(name);
+ attr = attlist.getValue("value");
+ if (attr != null && attr.length() > 0) {
+ extensionAttachment.setValue(attr);
} else {
throw new FOPException(elementName + " must have a value attribute.");
}
}
}
-
- /** {@inheritDoc} */
+
+ /**
+ * {@inheritDoc}
+ */
protected void endOfNode() throws FOPException {
super.endOfNode();
}
- /** {@inheritDoc} */
+ /**
+ * Instantiates extension attachment object
+ * @return extension attachment
+ */
+ protected abstract ExtensionAttachment instantiateExtensionAttachment();
+
+ /**
+ * {@inheritDoc}
+ */
public ExtensionAttachment getExtensionAttachment() {
- return this.setupCode;
+ if (extensionAttachment == null) {
+ this.extensionAttachment = (AFPExtensionAttachment)instantiateExtensionAttachment();
+ }
+ return this.extensionAttachment;
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public String getLocalName() {
return name;
}
diff --git a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java b/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java
index 62de923c8..bf534e3c7 100644
--- a/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java
+++ b/src/java/org/apache/fop/render/afp/modca/AFPDataStream.java
@@ -20,6 +20,7 @@
package org.apache.fop.render.afp.modca;
import java.awt.Color;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
@@ -28,7 +29,11 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.afp.AFPFontAttributes;
+import org.apache.fop.render.afp.DataObjectParameters;
+import org.apache.fop.render.afp.ImageObjectParameters;
+import org.apache.fop.render.afp.ResourceLevel;
import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.render.afp.tools.StringUtils;
/**
@@ -47,7 +52,7 @@ import org.apache.fop.render.afp.tools.StringUtils;
* them.
*
*/
-public class AFPDataStream {
+public class AFPDataStream extends AbstractResourceGroupContainer {
/**
* Static logging instance
@@ -81,6 +86,11 @@ public class AFPDataStream {
private PageObject currentPageObject = null;
/**
+ * The current resource group
+ */
+// private ResourceGroup currentResourceGroup = null;
+
+ /**
* The current overlay object
*/
private Overlay currentOverlay = null;
@@ -98,8 +108,7 @@ public class AFPDataStream {
/**
* The page group count
*/
-// not used
-// private int pageGroupCount = 0;
+ private int pageGroupCount = 0;
/**
* The overlay count
@@ -135,40 +144,71 @@ public class AFPDataStream {
* The outputstream for the data stream
*/
private OutputStream outputStream = null;
+
+ /**
+ * A mapping of external resource destinations to resource groups
+ */
+ private Map/*<String,ResourceGroup>*/ externalResourceGroups = null;
/**
* Default constructor for the AFPDataStream.
*/
public AFPDataStream() {
+ this.document = new Document();
+ }
+
+ private Document getDocument() {
+ return this.document;
+ }
+
+ private AbstractPageObject getCurrentPage() {
+ return this.currentPage;
}
/**
* The document is started by invoking this method which creates an instance
* of the AFP Document object.
*
- * @param docOutputStream
- * the outputStream which the document is written to.
- */
- public void startDocument(OutputStream docOutputStream) {
- if (document != null) {
- String msg = "Invalid state - document already started.";
- log.warn("startDocument():: " + msg);
- throw new IllegalStateException(msg);
+ * @param name
+ * the name of this document.
+ */
+ public void setDocumentName(String name) {
+// if (document != null) {
+// String msg = "Invalid state - document already started.";
+// log.warn("startDocument():: " + msg);
+// throw new IllegalStateException(msg);
+// }
+// if (document != null) {
+// String msg = "Invalid state - print file level document already started";
+// log.warn(msg);
+// throw new IllegalStateException(msg);
+// }
+
+ if (name != null) {
+ document.setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_BEGIN_DOCUMENT_REF,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR,
+ name);
}
-
- this.document = new Document();
- this.outputStream = docOutputStream;
}
/**
- * The document is ended by invoking this method which creates an instance
+ * Sets the OutputStream
+ * @param outputStream the AFP OutputStream
+ */
+ public void setOutputStream(OutputStream outputStream) {
+ this.outputStream = outputStream;
+ }
+
+ /**
+ * The document is written/ended by invoking this method which creates an instance
* of the AFP Document object and registers the start with a validation map
* which ensures that methods are not invoked out of the correct sequence.
*
* @throws java.io.IOException
* throws an I/O exception of some sort has occurred
*/
- public void endDocument() throws IOException {
+ public void write() throws IOException {
if (complete) {
String msg = "Invalid state - document already ended.";
log.warn("endDocument():: " + msg);
@@ -185,8 +225,22 @@ public class AFPDataStream {
endPageGroup();
}
- document.endDocument();
- document.writeDataStream(this.outputStream);
+ // Write out any external resource groups
+ if (externalResourceGroups != null) {
+ writeExternalResources();
+ }
+
+ // Write out any print-file level resources
+ if (hasResources()) {
+ getResourceGroup().writeDataStream(this.outputStream);
+ }
+
+ // Write out document
+ if (document != null) {
+ document.endDocument();
+ document.writeDataStream(this.outputStream);
+ }
+
this.outputStream.flush();
complete = true;
@@ -195,7 +249,7 @@ public class AFPDataStream {
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.
@@ -213,7 +267,6 @@ public class AFPDataStream {
*/
public void startPage(int pageWidth, int pageHeight, int pageRotation,
int pageWidthRes, int pageHeightRes) {
-
String pageName = "PGN"
+ StringUtils.lpad(String.valueOf(pageCount++), '0', 5);
@@ -229,34 +282,30 @@ public class AFPDataStream {
* the {@link #endOverlay()}method must be invoked to mark the overlay
* ending.
*
- * @param overlayX
+ * @param x
* the x position of the overlay on the page
- * @param overlayY
+ * @param y
* the y position of the overlay on the page
- * @param overlayWidth
+ * @param width
* the width of the overlay
- * @param overlayHeight
+ * @param height
* the height of the overlay
- * @param overlayWidthResolution
+ * @param widthRes
* the width resolution of the overlay
- * @param overlayHeightResolution
+ * @param heightRes
* the height resolution of the overlay
- * @param overlayRotation
+ * @param rotation
* the rotation of the overlay
*/
- public void startOverlay(int overlayX, int overlayY, int overlayWidth,
- int overlayHeight, int overlayWidthResolution,
- int overlayHeightResolution, int overlayRotation) {
-
+ public void startOverlay(int x, int y, int width, int height, int widthRes,
+ int heightRes, int rotation) {
String overlayName = "OVL"
+ StringUtils.lpad(String.valueOf(ovlCount++), '0', 5);
- currentOverlay = new Overlay(overlayName, overlayWidth, overlayHeight,
- overlayWidthResolution, overlayHeightResolution,
- overlayRotation);
- currentPageObject.addOverlay(currentOverlay);
- currentPageObject.createIncludePageOverlay(overlayName, overlayX,
- overlayY, 0);
+ currentOverlay = new Overlay(overlayName, width, height,
+ widthRes, heightRes, rotation);
+
+ currentPageObject.createIncludePageOverlay(overlayName, x, y, 0);
currentPage = currentOverlay;
setOffsets(0, 0, 0);
}
@@ -300,17 +349,13 @@ public class AFPDataStream {
/**
* Helper method to mark the end of the current page.
- *
- * @throws java.io.IOException
- * thrown when an I/O exception of some sort has occurred
*/
- public void endPage() throws IOException {
+ public void endPage() {
currentPageObject.endPage();
if (currentPageGroup != null) {
currentPageGroup.addPage(currentPageObject);
} else {
document.addPage(currentPageObject);
- document.writeDataStream(this.outputStream);
}
currentPageObject = null;
currentPage = null;
@@ -363,7 +408,6 @@ public class AFPDataStream {
currentPage.createFont(fontReference, font, size);
}
-
/**
* Helper method to create text on the current page, this method delegates
* to the current presentation text object in order to construct the text.
@@ -388,55 +432,46 @@ public class AFPDataStream {
currentPage.createText(fontReference, x + xOffset, y + yOffset, rotation,
col, vsci, ica, data);
}
-
+
/**
- * Returns an ImageObject used to create an image in the datastream.
- *
- * @param x
- * the x position of the image
- * @param y
- * the y position of the image
- * @param width
- * the width of the image
- * @param height
- * the height of the image
- * @param widthRes
- * the resolution width of the image
- * @param heightRes
- * the resolution height of the image
+ * Returns true if the resource exists within this resource group,
+ * false otherwise.
+ *
+ * @param uri the uri of the resource
+ * @return true if the resource exists within this resource group
+ */
+ public boolean resourceExists(String uri) {
+ return getResourceGroup().resourceExists(uri);
+ }
+
+ /**
+ * Returns an IncludeObject referencing an image in the datastream.
+ *
+ * @param params
+ * the unique uri of the image
* @return
- * a new image object
+ * a new include object referencing an image object
*/
- public ImageObject getImageObject(int x, int y, int width, int height,
- int widthRes, int heightRes) {
- ImageObject imageObj = currentPage.getImageObject();
- setObjectViewPort(imageObj, x, y, width, height, widthRes, heightRes);
- return imageObj;
+ public IncludeObject createImageObject(ImageObjectParameters params) {
+ ResourceLevel resourceLevel = params.getResourceLevel();
+ IncludeObject includeObj = getResourceGroup(resourceLevel).addObject(params);
+ currentPage.addObject(includeObj);
+ return includeObj;
}
/**
- * Returns an GraphicObject used to create an graphic in the datastream.
+ * Returns an IncludeObject referencing a graphic in the datastream.
*
- * @param x
- * the x position of the graphic
- * @param y
- * the y position of the graphic
- * @param width
- * the width of the graphic
- * @param height
- * the height of the graphic
- * @param widthRes
- * the resolution width of the graphic
- * @param heightRes
- * the resolution height of the graphic
+ * @param params
+ * the data object parameters
* @return
- * a new graphics object
+ * a new include object referencing the graphics object
*/
- public GraphicsObject getGraphicsObject(int x, int y, int width, int height,
- int widthRes, int heightRes) {
- GraphicsObject graphicsObj = currentPage.getGraphicsObject();
- setObjectViewPort(graphicsObj, x, y, width, height, widthRes, heightRes);
- return graphicsObj;
+ public IncludeObject createGraphicsObject(DataObjectParameters params) {
+ ResourceLevel resourceLevel = params.getResourceLevel();
+ IncludeObject includeObj = getResourceGroup(resourceLevel).addObject(params);
+ currentPage.addObject(includeObj);
+ return includeObj;
}
/**
@@ -559,9 +594,7 @@ public class AFPDataStream {
*/
public void createIncludePageOverlay(String name) {
currentPageObject.createIncludePageOverlay(name, 0, 0, rotation);
- ActiveEnvironmentGroup aeg = currentPageObject
- .getActiveEnvironmentGroup();
- aeg.createOverlay(name);
+ currentPageObject.getActiveEnvironmentGroup().createOverlay(name);
}
/**
@@ -571,10 +604,7 @@ public class AFPDataStream {
* the name of the medium map
*/
public void createInvokeMediumMap(String name) {
- if (currentPageGroup == null) {
- startPageGroup();
- }
- currentPageGroup.createInvokeMediumMap(name);
+ getCurrentPageGroup().createInvokeMediumMap(name);
}
/**
@@ -621,7 +651,7 @@ public class AFPDataStream {
for (int i = 0; i < attributes.length; i++) {
String name = (String) attributes[i].getKey();
String value = (String) attributes[i].getValue();
- currentPage.createTagLogicalElement(name, value);
+ getCurrentPage().createTagLogicalElement(name, value);
}
}
@@ -635,7 +665,7 @@ public class AFPDataStream {
for (int i = 0; i < attributes.length; i++) {
String name = (String) attributes[i].getKey();
String value = (String) attributes[i].getValue();
- currentPageGroup.createTagLogicalElement(name, value);
+ getCurrentPageGroup().createTagLogicalElement(name, value);
}
}
@@ -665,31 +695,33 @@ public class AFPDataStream {
currentPage.createNoOperation(content);
}
+ private PageGroup getCurrentPageGroup() {
+ if (currentPageGroup == null) {
+ String pageGroupName = "PGP"
+ + StringUtils.lpad(String.valueOf(pageGroupCount++), '0', 5);
+ this.currentPageGroup = new PageGroup(pageGroupName);
+ }
+ return currentPageGroup;
+ }
+
/**
* Start a new page group. When processing has finished on the current page
* group the {@link #endPageGroup()}method must be invoked to mark the page
* group ending.
*/
public void startPageGroup() {
-
- String pageGroupName = "PGP"
- + StringUtils.lpad(String.valueOf(pageCount++), '0', 5);
-
- currentPageGroup = new PageGroup(pageGroupName);
-
+ getCurrentPageGroup();
}
/**
* Helper method to mark the end of the page group.
- * @throws IOException thrown if an I/O exception of some sort has occurred
*/
- public void endPageGroup() throws IOException {
-
- currentPageGroup.endPageGroup();
- document.addPageGroup(currentPageGroup);
- document.writeDataStream(outputStream);
- currentPageGroup = null;
-
+ public void endPageGroup() {
+ if (currentPageGroup != null) {
+ currentPageGroup.endPageGroup();
+ document.addPageGroup(currentPageGroup);
+ currentPageGroup = null;
+ }
}
/**
@@ -700,7 +732,6 @@ public class AFPDataStream {
* The rotation in degrees.
*/
public void setPortraitRotation(int pageRotation) {
-
if (pageRotation == 0 || pageRotation == 90 || pageRotation == 180
|| pageRotation == 270) {
this.portraitRotation = pageRotation;
@@ -708,7 +739,6 @@ public class AFPDataStream {
throw new IllegalArgumentException(
"The portrait rotation must be one of the values 0, 90, 180, 270");
}
-
}
/**
@@ -719,7 +749,6 @@ public class AFPDataStream {
* The rotation in degrees.
*/
public void setLandscapeRotation(int pageRotation) {
-
if (pageRotation == 0 || pageRotation == 90 || pageRotation == 180
|| pageRotation == 270) {
this.landscapeRotation = pageRotation;
@@ -727,6 +756,72 @@ public class AFPDataStream {
throw new IllegalArgumentException(
"The landscape rotation must be one of the values 0, 90, 180, 270");
}
+ }
+
+ /**
+ * Writes out external AFP resources
+ */
+ private void writeExternalResources() {
+ // write any external resources
+ Iterator it = getExternalResourceGroups().keySet().iterator();
+ while (it.hasNext()) {
+ String externalDest = (String)it.next();
+ ResourceGroup resourceGroup
+ = (ResourceGroup)getExternalResourceGroups().get(externalDest);
+ OutputStream os = null;
+ try {
+ log.debug("Writing external AFP resource file " + externalDest);
+ os = new java.io.FileOutputStream(externalDest);
+ resourceGroup.writeDataStream(os);
+ } catch (FileNotFoundException e) {
+ log.error("Failed to open external AFP resource file "
+ + externalDest);
+ } catch (IOException e) {
+ log.error("An error occurred when attempting to write external AFP resource file "
+ + externalDest);
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ log.error("Failed to close outputstream for external AFP resource file "
+ + externalDest);
+ }
+ }
+ }
+ }
+ }
+ /**
+ * Returns the resource group for a given resource level
+ * @param resourceLevel a resource level
+ * @return a resource group container for the given level
+ */
+ private ResourceGroup getResourceGroup(ResourceLevel resourceLevel) {
+ ResourceGroup resourceGroup = null;
+ if (resourceLevel.isPrintFile()) {
+ resourceGroup = this.getResourceGroup();
+ } else if (resourceLevel.isDocument()) {
+ resourceGroup = document.getResourceGroup();
+ } else if (resourceLevel.isPageGroup()) {
+ resourceGroup = getCurrentPageGroup().getResourceGroup();
+ } else if (resourceLevel.isPage()) {
+ resourceGroup = getCurrentPage().getResourceGroup();
+ } else if (resourceLevel.isExternal()) {
+ String externalDest = resourceLevel.getExternalDest();
+ resourceGroup = (ResourceGroup)getExternalResourceGroups().get(externalDest);
+ if (resourceGroup == null) {
+ resourceGroup = new ResourceGroup();
+ externalResourceGroups.put(externalDest, resourceGroup);
+ }
+ }
+ return resourceGroup;
+ }
+
+ private Map/*<String,ResourceGroup>*/ getExternalResourceGroups() {
+ if (externalResourceGroups == null) {
+ externalResourceGroups = new java.util.HashMap();
+ }
+ return externalResourceGroups;
}
}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java
index cd8b25810..26d42b2d4 100644
--- a/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractAFPObject.java
@@ -21,8 +21,8 @@ package org.apache.fop.render.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -50,16 +50,18 @@ public abstract class AbstractAFPObject {
/**
* Help method to write a set of AFPObjects to the AFP datastream.
- * @param afpObjects a list of AFPObjects
+ * @param objects a list of AFPObjects
* @param os The stream to write to
* @throws java.io.IOException in the event that an I/O exception occurred
*/
- protected void writeObjectList(List afpObjects, OutputStream os)
+ protected void writeObjects(Collection/*<AbstractAFPObject>*/ objects, OutputStream os)
throws IOException {
-
- Iterator it = afpObjects.iterator();
- while (it.hasNext()) {
- ((AbstractAFPObject)it.next()).writeDataStream(os);
+ if (objects != null) {
+ for (Iterator it = objects.iterator(); it.hasNext();) {
+ Object obj1 = it.next();
+ AbstractAFPObject obj = (AbstractAFPObject)obj1;
+ obj.writeDataStream(os);
+ }
}
}
-}
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java
index cf5aad382..aa97065d1 100644
--- a/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractDataObject.java
@@ -22,7 +22,7 @@ package org.apache.fop.render.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.render.afp.modca.goca.AbstractGraphicsContainer;
+import org.apache.fop.render.afp.goca.AbstractGraphicsContainer;
/**
* Abstract base class used by the ImageObject and GraphicsObject which both
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/AbstractEnvironmentGroup.java
new file mode 100644
index 000000000..3f371d628
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractEnvironmentGroup.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * A base class that encapsulates common features of
+ * ActiveEnvironmentGroup and ResourceEnvironmentGroup
+ */
+public abstract class AbstractEnvironmentGroup extends AbstractNamedAFPObject {
+
+ /**
+ * The collection of MapPageOverlay objects
+ */
+ protected List mapPageOverlays = null;
+
+ /**
+ * Main constructor
+ * @param name the object name
+ */
+ public AbstractEnvironmentGroup(String name) {
+ super(name);
+ }
+
+ private List getMapPageOverlays() {
+ if (mapPageOverlays == null) {
+ mapPageOverlays = new java.util.ArrayList();
+ }
+ return mapPageOverlays;
+ }
+
+ /**
+ * Actually creates the MPO object.
+ * Also creates the supporting object (an IPO)
+ * @param name the name of the overlay to be used
+ */
+ public void createOverlay(String name) {
+ MapPageOverlay mpo = getCurrentMapPageOverlay();
+ if (mpo == null) {
+ mpo = new MapPageOverlay();
+ getMapPageOverlays().add(mpo);
+ }
+
+ try {
+ mpo.addOverlay(name);
+ } catch (MaximumSizeExceededException msee) {
+ mpo = new MapPageOverlay();
+ getMapPageOverlays().add(mpo);
+ try {
+ mpo.addOverlay(name);
+ } catch (MaximumSizeExceededException ex) {
+ // Should never happen (but log just in case)
+ log.error("createOverlay():: resulted in a MaximumSizeExceededException");
+ }
+ }
+ }
+
+ /**
+ * Getter method for the most recent MapPageOverlay added to the
+ * Active Environment Group (returns null if no MapPageOverlay exist)
+ * @return the most recent Map Coded Font
+ */
+ private MapPageOverlay getCurrentMapPageOverlay() {
+ if (mapPageOverlays != null && mapPageOverlays.size() > 0) {
+ return (MapPageOverlay) mapPageOverlays.get(mapPageOverlays.size() - 1);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+ if (mapPageOverlays != null) {
+ writeObjects(mapPageOverlays, os);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java
index 7545ee3af..393cff84b 100644
--- a/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractNamedAFPObject.java
@@ -18,14 +18,17 @@
/* $Id$ */
package org.apache.fop.render.afp.modca;
+
import java.io.UnsupportedEncodingException;
/**
* This is the base class for all named data stream objects.
* A named data stream object has an 8 byte EBCIDIC name.
*/
-public abstract class AbstractNamedAFPObject extends AbstractAFPObject {
-
+public abstract class AbstractNamedAFPObject extends AbstractStructuredAFPObject {
+
+ private static final int DEFAULT_NAME_LENGTH = 8;
+
/**
* The actual name of the object
*/
@@ -41,22 +44,13 @@ public abstract class AbstractNamedAFPObject extends AbstractAFPObject {
*/
protected AbstractNamedAFPObject() {
}
-
- private static final int DEFAULT_NAME_LENGTH = 8;
-
- /**
- * @return the name length of this object
- */
- protected int getNameLength() {
- return DEFAULT_NAME_LENGTH;
- }
-
+
/**
* Constructor for the ActiveEnvironmentGroup, this takes a
* name parameter which should be 8 characters long.
* @param name the object name
*/
- public AbstractNamedAFPObject(String name) {
+ protected AbstractNamedAFPObject(String name) {
int nameLen = getNameLength();
if (name.length() < nameLen) {
this.name = (name + " ").substring(0, nameLen);
@@ -66,19 +60,27 @@ public abstract class AbstractNamedAFPObject extends AbstractAFPObject {
} else {
this.name = name;
}
-
try {
-
this.nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
-
} catch (UnsupportedEncodingException usee) {
-
this.nameBytes = name.getBytes();
log.warn(
"Constructor:: UnsupportedEncodingException translating the name "
+ name);
-
}
-
+ }
+
+ /**
+ * @return the name length of this object
+ */
+ protected int getNameLength() {
+ return DEFAULT_NAME_LENGTH;
+ }
+
+ /**
+ * @return the name of the page group
+ */
+ public String getName() {
+ return name;
}
}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java
index 4ffcc4d94..f373b5bf7 100644
--- a/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractPageObject.java
@@ -20,7 +20,8 @@
package org.apache.fop.render.afp.modca;
import java.awt.Color;
-import java.util.ArrayList;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.List;
import org.apache.fop.render.afp.fonts.AFPFont;
@@ -46,32 +47,27 @@ import org.apache.fop.render.afp.tools.StringUtils;
* in page state.
*
*/
-public abstract class AbstractPageObject extends AbstractNamedAFPObject {
+public abstract class AbstractPageObject extends AbstractResourceGroupContainer {
/**
* The active environment group for the page
*/
- protected ActiveEnvironmentGroup activeEnvironmentGroup = null;
+ protected ActiveEnvironmentGroup activeEnvironmentGroup;
/**
* The presentation text object, we only have one per page
*/
- private PresentationTextObject presentationTextObject = null;
-
- /**
- * The list of objects within the page
- */
- protected List objects = new ArrayList();
+ private PresentationTextObject presentationTextObject;
/**
* The list of tag logical elements
*/
- protected ArrayList tagLogicalElements = new ArrayList();
+ protected List tagLogicalElements;
/**
* The list of the include page segments
*/
- protected ArrayList segments = new ArrayList();
+ protected List segments;
/**
* The page width
@@ -112,8 +108,8 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
*/
public AbstractPageObject(String name, int width, int height, int rotation,
int widthRes, int heightRes) {
-
super(name);
+
this.width = width;
this.height = height;
this.rotation = rotation;
@@ -121,7 +117,8 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
/**
* Every page object must have an ActiveEnvironmentGroup
*/
- activeEnvironmentGroup = new ActiveEnvironmentGroup(width, height, widthRes, heightRes);
+ this.activeEnvironmentGroup = new ActiveEnvironmentGroup(
+ width, height, widthRes, heightRes);
if (rotation != 0) {
switch (rotation) {
@@ -152,7 +149,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
* the point size of the font
*/
public void createFont(int fontReference, AFPFont font, int size) {
- activeEnvironmentGroup.createFont(fontReference, font, size, 0);
+ getActiveEnvironmentGroup().createFont(fontReference, font, size, 0);
}
/**
@@ -183,7 +180,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
* Helper method to create text on the current page, this method delegates
* to the presentation text object in order to construct the text.
*
- * @param fontReference
+ * @param fontRef
* the font number used as the resource identifier
* @param x
* the x coordinate of the text data
@@ -200,15 +197,15 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
* @param data
* the text data to create
*/
- public void createText(int fontReference, int x, int y, int textRotation, Color col,
+ public void createText(int fontRef, int x, int y, int textRotation, Color col,
int vsci, int ica, byte[] data) {
getPresentationTextObject().createTextData(
- fontReference, x, y, textRotation, col, vsci, ica, data);
+ fontRef, x, y, textRotation, col, vsci, ica, data);
}
/**
* Helper method to mark the end of the page. This should end the control
- * sequence on the current presenation text object.
+ * sequence on the current presentation text object.
*/
public void endPage() {
if (presentationTextObject != null) {
@@ -237,14 +234,11 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
* @param blue
* the blue value
*/
- public void createShading(int x, int y, int w, int h, int red, int green,
- int blue) {
-
+ public void createShading(int x, int y, int w, int h, int red, int green, int blue) {
int xCoord = 0;
int yCoord = 0;
int areaWidth = 0;
int areaHeight = 0;
-
switch (rotation) {
case 90:
xCoord = areaWidth - y - h;
@@ -278,7 +272,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
int greyscale = Math.round((shade / 255) * 16);
String imageName = "IMG"
- + StringUtils.lpad(String.valueOf(objects.size() + 1),
+ + StringUtils.lpad(String.valueOf(getResourceCount() + 1),
'0', 5);
IMImageObject io = new IMImageObject(imageName);
@@ -291,17 +285,23 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
icp.setYSize(8);
//defining this as a resource
- ImageRasterData ird = new ImageRasterData(ImageRasterPattern
- .getRasterData(greyscale));
+ ImageRasterData ird = new ImageRasterData(
+ ImageRasterPattern.getRasterData(greyscale));
io.setImageOutputControl(ioc);
io.setImageInputDescriptor(iid);
io.setImageCellPosition(icp);
io.setImageRasterData(ird);
- objects.add(io);
-
+ addObject(io);
}
+ private void endPresentationObject() {
+ if (presentationTextObject != null) {
+ presentationTextObject.endControlSequence();
+ presentationTextObject = null;
+ }
+ }
+
/**
* Helper method to create a presentation text object
* on the current page and to return the object.
@@ -310,49 +310,12 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
private PresentationTextObject getPresentationTextObject() {
if (presentationTextObject == null) {
this.presentationTextObject = new PresentationTextObject();
- objects.add(this.presentationTextObject);
+ addObject(this.presentationTextObject);
}
return presentationTextObject;
}
/**
- * Helper method to create an image on the current page and to return
- * the object.
- * @return the image object
- */
- public ImageObject getImageObject() {
-
- if (presentationTextObject != null) {
- presentationTextObject.endControlSequence();
- presentationTextObject = null;
- }
- String imageName = "IMG"
- + StringUtils.lpad(String.valueOf(objects.size() + 1),
- '0', 5);
- ImageObject imageObj = new ImageObject(imageName);
- objects.add(imageObj);
- return imageObj;
- }
-
- /**
- * Helper method to create a graphic on the current page and to return
- * the object.
- * @return the graphics object
- */
- public GraphicsObject getGraphicsObject() {
- if (presentationTextObject != null) {
- presentationTextObject.endControlSequence();
- presentationTextObject = null;
- }
- String graphicName = "GRA"
- + StringUtils.lpad(String.valueOf(objects.size() + 1),
- '0', 5);
- GraphicsObject graphicsObj = new GraphicsObject(graphicName);
- objects.add(graphicsObj);
- return graphicsObj;
- }
-
- /**
* Creates a TagLogicalElement on the page.
*
* @param name
@@ -362,6 +325,9 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
*/
public void createTagLogicalElement(String name, String value) {
TagLogicalElement tle = new TagLogicalElement(name, value);
+ if (tagLogicalElements == null) {
+ tagLogicalElements = new java.util.ArrayList();
+ }
tagLogicalElements.add(tle);
}
@@ -371,8 +337,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
* @param content the byte data
*/
public void createNoOperation(String content) {
- NoOperation noOp = new NoOperation(content);
- objects.add(noOp);
+ addObject(new NoOperation(content));
}
/**
@@ -387,6 +352,9 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
*/
public void createIncludePageSegment(String name, int xCoor, int yCoor) {
IncludePageSegment ips = new IncludePageSegment(name, xCoor, yCoor);
+ if (segments == null) {
+ segments = new java.util.ArrayList();
+ }
segments.add(ips);
}
@@ -430,4 +398,54 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject {
public int getRotation() {
return rotation;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+ getActiveEnvironmentGroup().writeDataStream(os);
+ writeObjects(segments, os);
+ writeObjects(tagLogicalElements, os);
+ writeObjects(objects, os);
+ }
+
+// /**
+// * {@inheritDoc}
+// */
+// public IncludeObject createImageObject(ImageObjectParameters params) {
+// endPresentationObject();
+// return super.createImageObject(params);
+// }
+//
+// /**
+// * {@inheritDoc}
+// */
+// public IncludeObject createGraphicsObject(DataObjectParameters params) {
+// endPresentationObject();
+// return super.createGraphicsObject(params);
+// }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void addObject(AbstractStructuredAFPObject obj) {
+ if (obj instanceof IncludeObject) {
+ IncludeObject includeObj = (IncludeObject)obj;
+ AbstractStructuredAFPObject refObj = includeObj.getReferencedObject();
+ if (refObj instanceof ImageObject || refObj instanceof GraphicsObject) {
+ getActiveEnvironmentGroup().createResource(refObj);
+ }
+ }
+ endPresentationObject();
+ super.addObject(obj);
+ }
+
+// /**
+// * {@inheritDoc}
+// */
+// protected void addObject(AbstractStructuredAFPObject obj) {
+// endPresentationObject();
+// super.addObject(obj);
+// }
}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractPreparedAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractPreparedAFPObject.java
new file mode 100644
index 000000000..e40aa1b4f
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractPreparedAFPObject.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * A base class that carries out early preparation of structured field data
+ * for the AFP object (so the data length can be pre-calculated)
+ */
+public abstract class AbstractPreparedAFPObject extends AbstractNamedAFPObject
+implements PreparedAFPObject {
+
+ /** structured field data to be written */
+ protected byte[] data = null;
+
+ /**
+ * Default constructor
+ */
+ public AbstractPreparedAFPObject() {
+ }
+
+ /**
+ * Named constructor
+ * @param name the name of this AFP object
+ */
+ public AbstractPreparedAFPObject(String name) {
+ super(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os); // write triplets
+ if (this.data != null) {
+ os.write(this.data);
+ }
+ }
+
+ /**
+ * @return the start data length of this structured field
+ */
+ protected int getStartDataLength() {
+ return 0;
+ }
+
+ /**
+ * @return the data length of the structured field data of this AFP object
+ */
+ public int getDataLength() {
+ if (this.data != null) {
+ return this.data.length;
+ }
+ return 0;
+ }
+
+ /**
+ * @return the structured field length
+ */
+ protected int getLength() {
+ return getStartDataLength() + getTripletDataLength() + getDataLength();
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java
new file mode 100644
index 000000000..eac4b778f
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceEnvironmentGroupContainer.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+/**
+ * An abstract class which encapsulates the common features of
+ * Document and PageGroup resource containers
+ */
+public abstract class AbstractResourceEnvironmentGroupContainer
+ extends AbstractResourceGroupContainer {
+
+ /**
+ * The resource environment group used to store complex resources
+ */
+ protected ResourceEnvironmentGroup resourceEnvironmentGroup = null;
+
+ /**
+ * Main constructor
+ * @param name the name of this resource container
+ */
+ public AbstractResourceEnvironmentGroupContainer(String name) {
+ super(name);
+ }
+
+ /**
+ * Adds a page to the resource container.
+ * @param page - the Page object
+ */
+ public void addPage(PageObject page) {
+ addObject(page);
+ }
+
+ /**
+ * Adds a PageGroup to the resource container.
+ * @param pageGroup the PageGroup object
+ */
+ public void addPageGroup(PageGroup pageGroup) {
+ addObject(pageGroup);
+ }
+
+ /**
+ * Creates an InvokeMediaMap on the page.
+ *
+ * @param name
+ * the name of the media map
+ */
+ public void createInvokeMediumMap(String name) {
+ addObject(new InvokeMediumMap(name));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+ if (resourceEnvironmentGroup != null) {
+ resourceEnvironmentGroup.writeDataStream(os);
+ }
+ if (objects != null) {
+ for (Iterator it = objects.iterator(); it.hasNext();) {
+ AbstractAFPObject ao = (AbstractAFPObject)it.next();
+ if (ao instanceof PageObject && ((PageObject)ao).isComplete()
+ || ao instanceof PageGroup && ((PageGroup)ao).isComplete()) {
+ ao.writeDataStream(os);
+ it.remove();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ private ResourceEnvironmentGroup getResourceEnvironmentGroup() {
+ if (resourceEnvironmentGroup == null) {
+ this.resourceEnvironmentGroup = new ResourceEnvironmentGroup();
+ }
+ return this.resourceEnvironmentGroup;
+ }
+
+ /**
+ * Adds a resource mapping to this resource environment group
+ * @param obj a resource to be referenced in this resource environment group
+ */
+ protected void addResource(AbstractStructuredAFPObject obj) {
+ getResourceEnvironmentGroup().addObject(obj);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java
new file mode 100644
index 000000000..e8e25b6b8
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractResourceGroupContainer.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Set;
+
+import org.apache.fop.render.afp.DataObjectParameters;
+import org.apache.fop.render.afp.ImageObjectParameters;
+
+/**
+ * An abstract container of resource objects
+ */
+public abstract class AbstractResourceGroupContainer extends AbstractNamedAFPObject {
+ /**
+ * The resource group object
+ */
+ private ResourceGroup resourceGroup = null;
+
+ /**
+ * The list of objects within this resource container
+ */
+ protected Set/*<AbstractStructuredAFPObject>*/ objects = null;
+
+ /**
+ * Unnamed constructor
+ */
+ public AbstractResourceGroupContainer() {
+ }
+
+ /**
+ * Named constructor
+ * @param name the name of this resource container
+ */
+ public AbstractResourceGroupContainer(String name) {
+ super(name);
+ }
+
+ /**
+ * @return the number of resources in this container
+ */
+ protected int getResourceCount() {
+ if (resourceGroup != null) {
+ return resourceGroup.getResourceCount();
+ }
+ return 0;
+ }
+
+ /**
+ * Adds an AFP object to the resource group in this container
+ * @param obj an AFP object
+ */
+ protected void addObject(AbstractAFPObject obj) {
+ if (objects == null) {
+ this.objects = new java.util.LinkedHashSet/*<AbstractAFPObject>*/();
+ }
+ objects.add(obj);
+ }
+
+ /**
+ * @return true if this resource group container contains resources
+ */
+ protected boolean hasResources() {
+ return resourceGroup != null && resourceGroup.getResourceCount() > 0;
+ }
+
+ /**
+ * @return the resource group in this resource group container
+ */
+ protected ResourceGroup getResourceGroup() {
+ if (resourceGroup == null) {
+ resourceGroup = new ResourceGroup();
+ }
+ return resourceGroup;
+ }
+
+ /**
+ * Helper method to create an image on the current container and to return
+ * the object.
+ * @param params the image object parameters
+ * @return the image object
+ */
+ public IncludeObject createImageObject(ImageObjectParameters params) {
+ return getResourceGroup().addObject(params);
+ }
+
+ /**
+ * Helper method to create a graphic in the current container and to return
+ * the object.
+ * @param params the data object parameters
+ * @return the graphics object
+ */
+ public IncludeObject createGraphicsObject(DataObjectParameters params) {
+ return getResourceGroup().addObject(params);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+ if (resourceGroup != null) {
+ resourceGroup.writeDataStream(os);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java b/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java
index e061748ca..3c448b2ab 100644
--- a/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/AbstractStructuredAFPObject.java
@@ -19,65 +19,225 @@
package org.apache.fop.render.afp.modca;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.render.afp.modca.triplets.MeasurementUnitsTriplet;
+import org.apache.fop.render.afp.modca.triplets.ObjectAreaSizeTriplet;
+import org.apache.fop.render.afp.modca.triplets.ObjectClassificationTriplet;
+import org.apache.fop.render.afp.modca.triplets.Triplet;
/**
* An abstract class encapsulating an MODCA structured object
*/
-public abstract class AbstractStructuredAFPObject extends AbstractNamedAFPObject {
+public abstract class AbstractStructuredAFPObject extends AbstractAFPObject {
/**
+ * list of object triplets
+ */
+ protected List/*<Triplet>*/ triplets = null;
+
+ /**
+ * triplet data created from triplet list
+ */
+ protected byte[] tripletData = null;
+
+ /**
* Default constructor
*/
- public AbstractStructuredAFPObject() {
- super();
+ protected AbstractStructuredAFPObject() {
}
/**
- * Named constructor
- * @param name name of structured object
+ * @return the triplet data length
*/
- public AbstractStructuredAFPObject(String name) {
- super(name);
+ protected int getTripletDataLength() {
+ if (tripletData != null) {
+ return tripletData.length;
+ }
+ return 0;
}
-
+
/**
* Helper method to write the start of the Object.
* @param os The stream to write to
* @throws IOException an I/O exception if one occurred
*/
protected void writeStart(OutputStream os) throws IOException {
+ if (triplets != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ writeObjects(triplets, baos);
+ this.tripletData = baos.toByteArray();
+ }
}
/**
* Helper method to write the contents of the Object.
* @param os The stream to write to
- * @throws IOException an I/O exception if one occurred
+ * @throws IOException The stream to write to
*/
protected void writeContent(OutputStream os) throws IOException {
+ writeTriplets(os);
}
/**
+ * Writes any triplet data
+ * @param os The stream to write to
+ * @throws IOException The stream to write to
+ */
+ protected void writeTriplets(OutputStream os) throws IOException {
+ if (tripletData != null) {
+ os.write(tripletData);
+ } else if (triplets != null) {
+ writeObjects(triplets, os);
+ }
+ }
+
+ /**
* Helper method to write the end of the Object.
* @param os The stream to write to
* @throws IOException an I/O exception if one occurred
*/
protected void writeEnd(OutputStream os) throws IOException {
}
-
+
/**
* Accessor method to write the AFP datastream for the Image Object
* @param os The stream to write to
* @throws IOException in the event that an I/O exception occurred
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
+ public void writeDataStream(OutputStream os) throws IOException {
writeStart(os);
-
writeContent(os);
-
writeEnd(os);
- }
+ }
+
+ /**
+ * Returns the first matching triplet found in the structured field triplet list
+ * @param tripletId the triplet identifier
+ */
+ private Triplet getTriplet(byte tripletId) {
+ Iterator it = getTriplets().iterator();
+ while (it.hasNext()) {
+ Triplet triplet = (Triplet)it.next();
+ if (triplet.getId() == tripletId) {
+ return triplet;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param tripletId the triplet identifier
+ * @return true if the structured field has the given triplet
+ */
+ private boolean hasTriplet(byte tripletId) {
+ return getTriplet(tripletId) != null;
+ }
+
+ /**
+ * Adds a triplet to this structured object
+ * @param triplet the triplet to add
+ */
+ private void addTriplet(Triplet triplet) {
+ getTriplets().add(triplet);
+ }
+
+ /**
+ * Adds a list of triplets to the triplets contained within this structured field
+ * @param tripletCollection a collection of triplets
+ */
+ private void addTriplets(Collection/*<Triplet>*/ tripletCollection) {
+ if (tripletCollection != null) {
+ getTriplets().addAll(tripletCollection);
+ }
+ }
+
+ /**
+ * @return the triplet list pertaining to this resource
+ */
+ protected List/*<Triplet>*/ getTriplets() {
+ if (triplets == null) {
+ triplets = new java.util.ArrayList();
+ }
+ return triplets;
+ }
+
+ /**
+ * Sets the fully qualified name of this resource
+ * @param fqnType the fully qualified name type of this resource
+ * @param fqnFormat the fully qualified name format of this resource
+ * @param fqName the fully qualified name of this resource
+ */
+ public void setFullyQualifiedName(byte fqnType, byte fqnFormat, String fqName) {
+ byte[] fqNameBytes;
+ try {
+ fqNameBytes = fqName.getBytes(AFPConstants.EBCIDIC_ENCODING);
+ addTriplet(new FullyQualifiedNameTriplet(fqnType, fqnFormat, fqNameBytes));
+ } catch (UnsupportedEncodingException e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ /**
+ * @return the fully qualified name of this triplet or null if it does not exist
+ */
+ public String getFullyQualifiedName() {
+ FullyQualifiedNameTriplet fqNameTriplet
+ = (FullyQualifiedNameTriplet)getTriplet(Triplet.FULLY_QUALIFIED_NAME);
+ byte[] nameBytes = fqNameTriplet.getFullyQualifiedName();
+ if (nameBytes != null) {
+ try {
+ return new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
+ } catch (UnsupportedEncodingException e) {
+ log.error(e.getMessage());
+ }
+ } else {
+ log.warn(this + " has no fully qualified name");
+ }
+ return null;
+ }
+
+ /**
+ * Sets the objects classification
+ * @param objectClass the classification of the object
+ * @param componentId the component Id of the object
+ */
+ public void setObjectClassification(byte objectClass, byte componentId) {
+ addTriplet(new ObjectClassificationTriplet(objectClass, componentId));
+ }
+
+ /**
+ * Specifies the extent of an object area in the X and Y directions
+ * @param x the x direction extent
+ * @param y the y direction extent
+ */
+ public void setObjectAreaSize(int x, int y) {
+ addTriplet(new ObjectAreaSizeTriplet(x, y));
+ }
+
+ /**
+ * Sets the measurement units used to specify the units of measure
+ */
+ public void setMeasurementUnits() {
+ addTriplet(new MeasurementUnitsTriplet());
+ }
+
+ /**
+ * Sets a comment on this resource
+ * @param comment a comment string
+ */
+ public void setComment(String comment) {
+ try {
+ addTriplet(new Triplet(Triplet.COMMENT, comment));
+ } catch (UnsupportedEncodingException e) {
+ log.error(e.getMessage());
+ }
+ }
}
diff --git a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java
index eb537b0d7..845af4dfc 100644
--- a/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java
+++ b/src/java/org/apache/fop/render/afp/modca/ActiveEnvironmentGroup.java
@@ -18,6 +18,7 @@
/* $Id$ */
package org.apache.fop.render.afp.modca;
+
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
@@ -37,7 +38,7 @@ import org.apache.fop.render.afp.fonts.AFPFont;
* containing page or overlay.
*
*/
-public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
+public final class ActiveEnvironmentGroup extends AbstractEnvironmentGroup {
/**
* Default name for the active environment group
@@ -47,7 +48,12 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
/**
* The collection of MapCodedFont objects
*/
- private List mapCodedFonts = new java.util.ArrayList();
+ private List mapCodedFonts = null;
+
+ /**
+ * The collection of MapDataResource objects
+ */
+ private List mapDataResources = null;
/**
* The Object Area Descriptor for the active environment group
@@ -70,22 +76,14 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
private PageDescriptor pageDescriptor = null;
/**
- * The collection of MapPageOverlay objects
- */
- private List mapPageOverlays = new java.util.ArrayList();
-
- /**
* Default constructor for the ActiveEnvironmentGroup.
* @param width the page width
* @param height the page height
* @param widthRes the page width resolution
* @param heightRes the page height resolution
*/
- public ActiveEnvironmentGroup(int width, int height,
- int widthRes, int heightRes) {
-
+ public ActiveEnvironmentGroup(int width, int height, int widthRes, int heightRes) {
this(DEFAULT_NAME, width, height, widthRes, heightRes);
-
}
/**
@@ -97,9 +95,7 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
* @param widthRes the page width resolution
* @param heightRes the page height resolution
*/
- public ActiveEnvironmentGroup(String name, int width, int height,
- int widthRes, int heightRes) {
-
+ public ActiveEnvironmentGroup(String name, int width, int height, int widthRes, int heightRes) {
super(name);
// Create PageDescriptor
@@ -112,7 +108,6 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
// Create PresentationTextDataDescriptor
presentationTextDataDescriptor = new PresentationTextDescriptor(width, height,
widthRes, heightRes);
-
}
/**
@@ -122,10 +117,8 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
* @param rotation the rotation
*/
public void setPosition(int x, int y, int rotation) {
-
// Create ObjectAreaPosition
objectAreaPosition = new ObjectAreaPosition(x, y, rotation);
-
}
/**
@@ -134,9 +127,7 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
* @return the page descriptor object
*/
public PageDescriptor getPageDescriptor() {
-
return pageDescriptor;
-
}
/**
@@ -145,47 +136,36 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
* @return the presentation text descriptor
*/
public PresentationTextDescriptor getPresentationTextDataDescriptor() {
-
return presentationTextDataDescriptor;
-
}
/**
- * Accessor method to write the AFP datastream for the active environment group.
- * @param os The stream to write to
- * @throws java.io.IOException throws if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(mapCodedFonts, os);
-
- writeObjectList(mapPageOverlays, os);
-
- pageDescriptor.writeDataStream(os);
-
+ public void writeContent(OutputStream os) throws IOException {
+ super.writeTriplets(os);
+
+ writeObjects(mapCodedFonts, os);
+ writeObjects(mapPageOverlays, os);
+ writeObjects(mapDataResources, os);
+
+ if (pageDescriptor != null) {
+ pageDescriptor.writeDataStream(os);
+ }
if (objectAreaDescriptor != null && objectAreaPosition != null) {
objectAreaDescriptor.writeDataStream(os);
objectAreaPosition.writeDataStream(os);
}
-
- presentationTextDataDescriptor.writeDataStream(os);
-
- writeEnd(os);
-
+ if (presentationTextDataDescriptor != null) {
+ presentationTextDataDescriptor.writeDataStream(os);
+ }
}
/**
- * Helper method to write the start of the active environment group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -195,26 +175,17 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
- os.write(data);
-
+ os.write(data);
}
/**
- * Helper method to write the end of the active environment group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -224,130 +195,75 @@ public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
+ }
+ private List getMapCodedFonts() {
+ if (mapCodedFonts == null) {
+ mapCodedFonts = new java.util.ArrayList();
+ }
+ return mapCodedFonts;
+ }
+
+ private List getMapDataResources() {
+ if (mapDataResources == null) {
+ mapDataResources = new java.util.ArrayList();
+ }
+ return mapDataResources;
}
/**
* Method to create a map coded font object
- * @param fontReference the font number used as the resource identifier
+ * @param fontRef the font number used as the resource identifier
* @param font the font
* @param size the point size of the font
* @param orientation the orientation of the font (e.g. 0, 90, 180, 270)
*/
- public void createFont(
- int fontReference,
- AFPFont font,
- int size,
- int orientation) {
-
+ public void createFont(int fontRef, AFPFont font, int size, int orientation) {
MapCodedFont mcf = getCurrentMapCodedFont();
-
if (mcf == null) {
mcf = new MapCodedFont();
- mapCodedFonts.add(mcf);
+ getMapCodedFonts().add(mcf);
}
try {
-
- mcf.addFont(
- fontReference,
- font,
- size,
- orientation);
-
+ mcf.addFont(fontRef, font, size, orientation);
} catch (MaximumSizeExceededException msee) {
-
mcf = new MapCodedFont();
- mapCodedFonts.add(mcf);
+ getMapCodedFonts().add(mcf);
try {
-
- mcf.addFont(
- fontReference,
- font,
- size,
- orientation);
-
+ mcf.addFont(fontRef, font, size, orientation);
} catch (MaximumSizeExceededException ex) {
-
// Should never happen (but log just in case)
log.error("createFont():: resulted in a MaximumSizeExceededException");
-
- }
-
- }
-
- }
-
- /**
- * Actually creates the MPO object.
- * Also creates the supporting object (an IPO)
- * @param name the name of the overlay to be used
- */
- public void createOverlay(String name) {
-
- MapPageOverlay mpo = getCurrentMapPageOverlay();
-
- if (mpo == null) {
- mpo = new MapPageOverlay();
- mapPageOverlays.add(mpo);
- }
-
- try {
-
- mpo.addOverlay(name);
-
- } catch (MaximumSizeExceededException msee) {
- mpo = new MapPageOverlay();
- mapPageOverlays.add(mpo);
- try {
- mpo.addOverlay(name);
- } catch (MaximumSizeExceededException ex) {
- // Should never happen (but log just in case)
- log.error("createOverlay():: resulted in a MaximumSizeExceededException");
}
}
}
-
+
/**
* Getter method for the most recent MapCodedFont added to the
* Active Environment Group (returns null if no MapCodedFonts exist)
* @return the most recent Map Coded Font.
*/
private MapCodedFont getCurrentMapCodedFont() {
-
- int size = mapCodedFonts.size();
+ int size = getMapCodedFonts().size();
if (size > 0) {
- return (MapCodedFont) mapCodedFonts.get(mapCodedFonts.size() - 1);
+ return (MapCodedFont)mapCodedFonts.get(size - 1);
} else {
return null;
}
-
}
-
+
+
/**
- * Getter method for the most recent MapPageOverlay added to the
- * Active Environment Group (returns null if no MapPageOverlay exist)
- * @return the most recent Map Coded Font
+ * Method to create a map data resource object
+ * @param obj creates a map data resource entry for a given AFP data resource object
*/
- private MapPageOverlay getCurrentMapPageOverlay() {
-
- int size = mapPageOverlays.size();
- if (size > 0) {
- return (MapPageOverlay) mapPageOverlays.get(
- mapPageOverlays.size() - 1);
- } else {
- return null;
- }
-
+ public void createResource(AbstractStructuredAFPObject obj) {
+ getMapDataResources().add(new MapDataResource(obj));
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/Document.java b/src/java/org/apache/fop/render/afp/modca/Document.java
index 3d2d40a3a..72c65e8a7 100644
--- a/src/java/org/apache/fop/render/afp/modca/Document.java
+++ b/src/java/org/apache/fop/render/afp/modca/Document.java
@@ -18,10 +18,9 @@
/* $Id$ */
package org.apache.fop.render.afp.modca;
+
import java.io.IOException;
import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
/**
* The document is the highest level of the MO:DCA data-stream document
@@ -48,23 +47,13 @@ import java.util.List;
* document to be presented.
*
*/
-public final class Document extends AbstractNamedAFPObject {
+public final class Document extends AbstractResourceEnvironmentGroupContainer {
/**
- * Ststic default name reference
+ * Static default generated name reference
*/
private static final String DEFAULT_NAME = "DOC00001";
-
- /**
- * A list of the objects in the document
- */
- private List objects = new java.util.ArrayList();
-
- /**
- * The document started state
- */
- private boolean started = false;
-
+
/**
* The document completion state
*/
@@ -82,36 +71,14 @@ public final class Document extends AbstractNamedAFPObject {
* @param name The name of the document
*/
public Document(String name) {
-
super(name);
-
- }
-
- /**
- * Adds a page to the document.
- * @param page - the Page object
- */
- public void addPage(PageObject page) {
- if (!objects.contains(page)) {
- objects.add(page);
- }
- }
-
- /**
- * Adds a PageGroup to the document.
- * @param pageGroup the PageGroup object
- */
- public void addPageGroup(PageGroup pageGroup) {
- objects.add(pageGroup);
}
/**
* Method to mark the end of the page group.
*/
public void endDocument() {
-
complete = true;
-
}
/**
@@ -127,40 +94,17 @@ public final class Document extends AbstractNamedAFPObject {
* @param os The stream to write to
* @throws java.io.IOException thrown if an I/O exception of some sort has occurred
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- if (!started) {
- writeStart(os);
- started = true;
- }
-
- for (Iterator it = objects.iterator(); it.hasNext();) {
- AbstractAFPObject ao = (AbstractAFPObject)it.next();
- if (ao instanceof PageObject && ((PageObject)ao).isComplete()
- || ao instanceof PageGroup && ((PageGroup)ao).isComplete()) {
- ao.writeDataStream(os);
- it.remove();
- } else {
- break;
- }
+ public void writeDataStream(OutputStream os) throws IOException {
+ if (isComplete()) {
+ super.writeDataStream(os);
}
-
- if (complete) {
- writeEnd(os);
- }
-
}
/**
- * Helper method to write the start of the Document
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -170,26 +114,17 @@ public final class Document extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the Document.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -199,15 +134,16 @@ public final class Document extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return this.name;
+ }
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java
index 065ca6626..7e5f12877 100644
--- a/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/GraphicsObject.java
@@ -23,22 +23,22 @@ import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.fop.render.afp.modca.goca.GraphicsBox;
-import org.apache.fop.render.afp.modca.goca.GraphicsData;
-import org.apache.fop.render.afp.modca.goca.GraphicsFillet;
-import org.apache.fop.render.afp.modca.goca.GraphicsFullArc;
-import org.apache.fop.render.afp.modca.goca.GraphicsImageBegin;
-import org.apache.fop.render.afp.modca.goca.GraphicsImageData;
-import org.apache.fop.render.afp.modca.goca.GraphicsImageEnd;
-import org.apache.fop.render.afp.modca.goca.GraphicsLine;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetArcParameters;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetCharacterSet;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetCurrentPosition;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetLineType;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetLineWidth;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetPatternSymbol;
-import org.apache.fop.render.afp.modca.goca.GraphicsSetProcessColor;
-import org.apache.fop.render.afp.modca.goca.GraphicsString;
+import org.apache.fop.render.afp.goca.GraphicsBox;
+import org.apache.fop.render.afp.goca.GraphicsData;
+import org.apache.fop.render.afp.goca.GraphicsFillet;
+import org.apache.fop.render.afp.goca.GraphicsFullArc;
+import org.apache.fop.render.afp.goca.GraphicsImageBegin;
+import org.apache.fop.render.afp.goca.GraphicsImageData;
+import org.apache.fop.render.afp.goca.GraphicsImageEnd;
+import org.apache.fop.render.afp.goca.GraphicsLine;
+import org.apache.fop.render.afp.goca.GraphicsSetArcParameters;
+import org.apache.fop.render.afp.goca.GraphicsSetCharacterSet;
+import org.apache.fop.render.afp.goca.GraphicsSetCurrentPosition;
+import org.apache.fop.render.afp.goca.GraphicsSetLineType;
+import org.apache.fop.render.afp.goca.GraphicsSetLineWidth;
+import org.apache.fop.render.afp.goca.GraphicsSetPatternSymbol;
+import org.apache.fop.render.afp.goca.GraphicsSetProcessColor;
+import org.apache.fop.render.afp.goca.GraphicsString;
/**
* Top-level GOCA graphics object.
@@ -309,7 +309,7 @@ public class GraphicsObject extends AbstractDataObject {
* {@inheritDoc}
*/
public String toString() {
- return "GraphicsObject";
+ return "GraphicsObject: " + getName();
}
/**
diff --git a/src/java/org/apache/fop/render/afp/modca/IMImageObject.java b/src/java/org/apache/fop/render/afp/modca/IMImageObject.java
index bb43950dd..2afd3fa49 100644
--- a/src/java/org/apache/fop/render/afp/modca/IMImageObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/IMImageObject.java
@@ -63,9 +63,7 @@ public class IMImageObject extends AbstractNamedAFPObject {
* @param name The name of the image.
*/
public IMImageObject(String name) {
-
super(name);
-
}
/**
@@ -101,44 +99,29 @@ public class IMImageObject extends AbstractNamedAFPObject {
}
/**
- * Accessor method to write the AFP datastream for the IM Image Objetc
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
if (imageOutputControl != null) {
imageOutputControl.writeDataStream(os);
}
-
if (imageInputDescriptor != null) {
imageInputDescriptor.writeDataStream(os);
}
-
if (imageCellPosition != null) {
imageCellPosition.writeDataStream(os);
}
-
if (imageRasterData != null) {
imageRasterData.writeDataStream(os);
}
-
- writeEnd(os);
-
}
/**
- * Helper method to write the start of the IM Image Object.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -148,26 +131,17 @@ public class IMImageObject extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the IM Image Object.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -177,15 +151,9 @@ public class IMImageObject extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
}
diff --git a/src/java/org/apache/fop/render/afp/modca/ImageContent.java b/src/java/org/apache/fop/render/afp/modca/ImageContent.java
index e7fd538e1..4aea02901 100644
--- a/src/java/org/apache/fop/render/afp/modca/ImageContent.java
+++ b/src/java/org/apache/fop/render/afp/modca/ImageContent.java
@@ -26,7 +26,31 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
/**
* Image content IOCA object
*/
-public class ImageContent extends AbstractAFPObject {
+public class ImageContent extends AbstractStructuredAFPObject {
+
+ /**
+ * The CCITT T.4 Group 3 Coding Standard (G3 MH-Modified Huffman) is a
+ * compression method standardized by the International Telegraph and
+ * Telephone Consultative Committee (CCITT) for facsimile. It enables
+ * one-dimensional compression.
+ */
+ public static final byte COMPID_G3_MH = (byte)0x80;
+
+ /**
+ * The CCITT T.4 Group 3 Coding Option (G3 MR-Modified READ) is a
+ * compression method standardized by the International Telegraph and
+ * Telephone Consultative Committee (CCITT) for facsimile. It enables
+ * two-dimensional compression.
+ */
+ public static final byte COMPID_G3_MR = (byte)0x81;
+
+ /**
+ * The CCITT T.6 Group 4 Coding Standard (G4 MMR-Modified Modified READ) is a
+ * compression method standardized by the International Telegraph and
+ * Telephone Consultative Committee (CCITT) for facsimile. It enables
+ * two-dimensional compression.
+ */
+ public static final byte COMPID_G3_MMR = (byte)0x82;
/**
* The image size parameter
@@ -56,13 +80,12 @@ public class ImageContent extends AbstractAFPObject {
/**
* The image data
*/
- private byte[] data = null;
+ private byte[] imageData = null;
/**
* Constructor for the image content
*/
public ImageContent() {
-
}
/**
@@ -111,70 +134,55 @@ public class ImageContent extends AbstractAFPObject {
/**
* Set the data of the image.
- * @param dat the image data
+ * @param data the image data
*/
- public void setImageData(byte[] dat) {
- this.data = dat;
+ public void setImageData(byte[] data) {
+ this.imageData = data;
}
/**
- * Accessor method to write the AFP datastream for the Image Content
- * @param os The stream to write to
- * @throws java.io.IOException if an I/O exception occurs
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os) throws IOException {
-
- writeStart(os);
-
+ protected void writeContent(OutputStream os) throws IOException {
if (imageSizeParam != null) {
imageSizeParam.writeDataStream(os);
}
-
os.write(getImageEncodingParameter());
-
os.write(getImageIDESizeParameter());
-
os.write(getIDEStructureParameter());
-
os.write(getExternalAlgorithmParameter());
-
- if (data != null) {
+ if (imageData != null) {
int off = 0;
- while (off < data.length) {
- int len = Math.min(30000, data.length - off);
+ while (off < imageData.length) {
+ int len = Math.min(30000, imageData.length - off);
os.write(getImageDataStart(len));
- os.write(data, off, len);
+ os.write(imageData, off, len);
off += len;
}
}
-
- writeEnd(os);
-
}
/**
- * Helper method to write the start of the Image Content.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os) throws IOException {
- byte[] startData = new byte[] {
+ protected void writeStart(OutputStream os) throws IOException {
+ byte[] data = new byte[] {
(byte)0x91, // ID
0x01, // Length
(byte)0xff, // Object Type = IOCA Image Object
};
- os.write(startData);
+ os.write(data);
}
/**
- * Helper method to write the end of the Image Content.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os) throws IOException {
- byte[] endData = new byte[] {
+ protected void writeEnd(OutputStream os) throws IOException {
+ byte[] data = new byte[] {
(byte)0x93, // ID
0x00, // Length
};
- os.write(endData);
+ os.write(data);
}
/**
diff --git a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java b/src/java/org/apache/fop/render/afp/modca/ImageSegment.java
index 5f8454fa8..2876e8348 100644
--- a/src/java/org/apache/fop/render/afp/modca/ImageSegment.java
+++ b/src/java/org/apache/fop/render/afp/modca/ImageSegment.java
@@ -21,7 +21,6 @@ package org.apache.fop.render.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
/**
* An Image Segment is represented by a set of self-defining fields, fields
@@ -33,7 +32,7 @@ import java.io.UnsupportedEncodingException;
*
* Only one Image Content can exist within a single IOCA Image Segment.
*/
-public class ImageSegment extends AbstractAFPObject {
+public class ImageSegment extends AbstractNamedAFPObject {
/**
* Default name for the object environment group
@@ -41,16 +40,6 @@ public class ImageSegment extends AbstractAFPObject {
private static final String DEFAULT_NAME = "IS01";
/**
- * The name of the image segment
- */
- private String name;
-
- /**
- * The name of the image segment as EBCIDIC bytes
- */
- private byte[] nameBytes;
-
- /**
* The ImageContent for the image segment
*/
private ImageContent imageContent = null;
@@ -68,20 +57,14 @@ public class ImageSegment extends AbstractAFPObject {
* @param name The name of the image.
*/
public ImageSegment(String name) {
- if (name.length() != 4) {
- String msg = "Image segment name must be 4 characters long " + name;
- log.error("Constructor:: " + msg);
- throw new IllegalArgumentException(msg);
- }
- this.name = name;
- try {
- this.nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
- } catch (UnsupportedEncodingException usee) {
- this.nameBytes = name.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
- }
+ super(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected int getNameLength() {
+ return 4;
}
/**
@@ -155,43 +138,33 @@ public class ImageSegment extends AbstractAFPObject {
}
/**
- * Accessor method to write the AFP datastream for the Image Segment
- * @param os The stream to write to
- * @throws java.io.IOException if an I/O exception occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os) throws IOException {
- writeStart(os);
+ public void writeContent(OutputStream os) throws IOException {
if (imageContent != null) {
imageContent.writeDataStream(os);
}
- writeEnd(os);
}
/**
- * Helper method to write the start of the Image Segment.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os) throws IOException {
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[] {
0x70, // ID
0x04, // Length
- 0x00, // Name byte 1
- 0x00, // Name byte 2
- 0x00, // Name byte 3
- 0x00, // Name byte 4
+ nameBytes[0], // Name byte 1
+ nameBytes[1], // Name byte 2
+ nameBytes[2], // Name byte 3
+ nameBytes[3], // Name byte 4
};
- for (int i = 0; i < nameBytes.length; i++) {
- data[2 + i] = nameBytes[i];
- }
os.write(data);
-
}
/**
- * Helper method to write the end of the Image Segment.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os) throws IOException {
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[] {
0x71, // ID
0x00, // Length
diff --git a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java b/src/java/org/apache/fop/render/afp/modca/IncludeObject.java
index 890fdcd9d..0fceff893 100644
--- a/src/java/org/apache/fop/render/afp/modca/IncludeObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/IncludeObject.java
@@ -40,28 +40,92 @@ import org.apache.fop.render.afp.tools.BinaryUtils;
public class IncludeObject extends AbstractNamedAFPObject {
/**
- * The object type
+ * the include object is of type page segment
*/
- private byte objectType = (byte) 0x92;
+ protected static final byte TYPE_PAGE_SEGMENT = (byte)0x5F;
+
+ /**
+ * the include object is of type other
+ */
+ protected static final byte TYPE_OTHER = (byte)0x92;
+
+ /**
+ * the include object is of type graphic
+ */
+ protected static final byte TYPE_GRAPHIC = (byte)0xBB;
+
+ /**
+ * the included object is of type barcode
+ */
+ protected static final byte TYPE_BARCODE = (byte)0xEB;
+
+ /**
+ * the included object is of type image
+ */
+ protected static final byte TYPE_IMAGE = (byte)0xFB;
+
+ /**
+ * The object type (default is other)
+ */
+ private byte objectType = TYPE_OTHER;
/**
* The orientation on the include object
*/
- private int orientation = 0;
+ private int orientation = -1;
+
+ /**
+ * The X-axis origin of the object area
+ */
+ private int xOffset = -1;
+
+ /**
+ * The Y-axis origin of the object area
+ */
+ private int yOffset = -1;
+
+ /**
+ * The X-axis origin defined in the object
+ */
+ private int xContentOffset = -1;
/**
+ * The Y-axis origin defined in the object
+ */
+ private int yContentOffset = -1;
+
+ /**
+ * The object referenced by this include object
+ */
+ private AbstractStructuredAFPObject referencedObject = null;
+
+ /**
* Constructor for the include object with the specified name, the name must
* be a fixed length of eight characters and is the name of the referenced
* object.
*
- * @param name
- * the name of the image
+ * @param resourceObj
+ * the resource object wrapper
*/
- public IncludeObject(String name) {
-
- super(name);
- objectType = (byte) 0xFB;
+ public IncludeObject(ResourceObject resourceObj) {
+ super(resourceObj.getResource().getName());
+ this.referencedObject = resourceObj.getResource();
+ if (referencedObject instanceof ImageObject) {
+ this.objectType = TYPE_IMAGE;
+ } else if (referencedObject instanceof GraphicsObject) {
+ this.objectType = TYPE_GRAPHIC;
+ } else if (referencedObject instanceof PageSegment) {
+ this.objectType = TYPE_PAGE_SEGMENT;
+ } else {
+ this.objectType = TYPE_OTHER;
+ }
+ }
+ /**
+ * @return the object referenced by this include object
+ */
+ public AbstractStructuredAFPObject getReferencedObject() {
+ return referencedObject;
}
/**
@@ -71,7 +135,6 @@ public class IncludeObject extends AbstractNamedAFPObject {
* The orientation (0,90, 180, 270)
*/
public void setOrientation(int orientation) {
-
if (orientation == 0 || orientation == 90 || orientation == 180
|| orientation == 270) {
this.orientation = orientation;
@@ -79,25 +142,39 @@ public class IncludeObject extends AbstractNamedAFPObject {
throw new IllegalArgumentException(
"The orientation must be one of the values 0, 90, 180, 270");
}
-
}
/**
- * Accessor method to write the AFP datastream for the Include Object
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * Sets the x and y offset to the origin in the object area
+ * @param x the X-axis origin of the object area
+ * @param y the Y-axis origin of the object area
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[37];
-
+ public void setObjectArea(int x, int y) {
+ this.xOffset = x;
+ this.yOffset = y;
+ }
+
+ /**
+ * Sets the x and y offset of the content area to the object area
+ * @param x the X-axis origin defined in the object
+ * @param y the Y-axis origin defined in the object
+ */
+ public void setContentArea(int x, int y) {
+ this.xContentOffset = x;
+ this.yContentOffset = y;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeDataStream(OutputStream os) throws IOException {
+ byte[] data = new byte[36];
data[0] = 0x5A;
// Set the total record length
- byte[] rl1 = BinaryUtils.convert(36, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
+ byte[] len = BinaryUtils.convert(35, 2); //Ignore first byte
+ data[1] = len[0];
+ data[2] = len[1];
// Structured field ID for a IOB
data[3] = (byte) 0xD3;
@@ -112,60 +189,91 @@ public class IncludeObject extends AbstractNamedAFPObject {
data[9 + i] = nameBytes[i];
}
- data[17] = 0x00;
+ data[17] = 0x00; // reserved
data[18] = objectType;
- // XoaOset
- data[20] = (byte) 0xFF;
- data[21] = (byte) 0xFF;
- data[22] = (byte) 0xFF;
+ //XoaOset (object area)
+ if (xOffset > 0) {
+ byte[] x = BinaryUtils.convert(xOffset, 3);
+ data[19] = x[0];
+ data[20] = x[1];
+ data[21] = x[2];
+ } else {
+ data[19] = (byte)0xFF;
+ data[20] = (byte)0xFF;
+ data[21] = (byte)0xFF;
+ }
- // YoaOset
- data[23] = (byte) 0xFF;
- data[24] = (byte) 0xFF;
- data[25] = (byte) 0xFF;
+ // YoaOset (object area)
+ if (yOffset > 0) {
+ byte[] y = BinaryUtils.convert(yOffset, 3);
+ data[22] = y[0];
+ data[23] = y[1];
+ data[24] = y[2];
+ } else {
+ data[22] = (byte)0xFF;
+ data[23] = (byte)0xFF;
+ data[24] = (byte)0xFF;
+ }
switch (orientation) {
+ case -1: // use x/y axis orientation defined in object
+ data[25] = (byte)0xFF; // x axis rotation
+ data[26] = (byte)0xFF; //
+ data[27] = (byte)0xFF; // y axis rotation
+ data[28] = (byte)0xFF;
+ break;
case 90:
- data[26] = 0x2D;
- data[27] = 0x00;
- data[28] = 0x5A;
- data[29] = 0x00;
+ data[25] = 0x2D;
+ data[26] = 0x00;
+ data[27] = 0x5A;
+ data[28] = 0x00;
break;
case 180:
- data[26] = 0x5A;
- data[27] = 0x00;
- data[28] = (byte) 0x87;
- data[29] = 0x00;
+ data[25] = 0x5A;
+ data[25] = 0x00;
+ data[27] = (byte)0x87;
+ data[28] = 0x00;
break;
case 270:
- data[26] = (byte) 0x87;
+ data[25] = (byte)0x87;
+ data[26] = 0x00;
data[27] = 0x00;
data[28] = 0x00;
- data[29] = 0x00;
break;
default:
+ data[25] = 0x00;
data[26] = 0x00;
- data[27] = 0x00;
- data[28] = 0x2D;
- data[29] = 0x00;
+ data[27] = 0x2D;
+ data[28] = 0x00;
break;
}
- // XocaOset
- data[30] = (byte) 0xFF;
- data[31] = (byte) 0xFF;
- data[32] = (byte) 0xFF;
-
- // YocaOset
- data[33] = (byte) 0xFF;
- data[34] = (byte) 0xFF;
- data[35] = (byte) 0xFF;
+ // XocaOset (object content)
+ if (xContentOffset > 0) {
+ byte[] y = BinaryUtils.convert(xContentOffset, 3);
+ data[29] = y[0];
+ data[30] = y[1];
+ data[31] = y[2];
+ } else {
+ data[29] = (byte)0xFF;
+ data[30] = (byte)0xFF;
+ data[31] = (byte)0xFF;
+ }
- data[36] = 0x01;
+ // YocaOset (object content)
+ if (yContentOffset > 0) {
+ byte[] y = BinaryUtils.convert(yContentOffset, 3);
+ data[32] = y[0];
+ data[33] = y[1];
+ data[34] = y[2];
+ } else {
+ data[32] = (byte)0xFF;
+ data[33] = (byte)0xFF;
+ data[34] = (byte)0xFF;
+ }
+ data[35] = 0x01;
os.write(data);
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java b/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java
index 7c52fe0a2..8a7d4720a 100644
--- a/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java
+++ b/src/java/org/apache/fop/render/afp/modca/IncludePageOverlay.java
@@ -69,7 +69,7 @@ public class IncludePageOverlay extends AbstractNamedAFPObject {
}
/**
- * Sets the orienation to use for the overlay.
+ * Sets the orientation to use for the overlay.
*
* @param orientation
* The orientation (0,90, 180, 270)
@@ -85,15 +85,10 @@ public class IncludePageOverlay extends AbstractNamedAFPObject {
}
/**
- * Accessor method to write the AFP datastream for the Include Page Overlay
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
+ public void writeDataStream(OutputStream os) throws IOException {
byte[] data = new byte[25]; //(9 +16)
-
data[0] = 0x5A;
// Set the total record length
diff --git a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java b/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java
index 7792a7162..b87222c00 100644
--- a/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java
+++ b/src/java/org/apache/fop/render/afp/modca/IncludePageSegment.java
@@ -59,35 +59,29 @@ public class IncludePageSegment extends AbstractNamedAFPObject {
* @param y The y position
*/
public IncludePageSegment(String name, int x, int y) {
-
super(name);
this.x = BinaryUtils.convert(x, 3);
this.y = BinaryUtils.convert(y, 3);
-
}
/**
- * Accessor method to write the AFP datastream for the Include Page Segment
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
+ public void writeDataStream(OutputStream os) throws IOException {
byte[] data = new byte[23]; //(9 +14)
data[0] = 0x5A;
// Set the total record length
- byte[] rl1 = BinaryUtils.convert(22, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
+ byte[] len = BinaryUtils.convert(22, 2); //Ignore first byte
+ data[1] = len[0];
+ data[2] = len[1];
// Structured field ID for a IPS
data[3] = (byte) 0xD3;
data[4] = (byte) 0xAF;
data[5] = (byte) 0x5F;
-
data[6] = 0x00; // Reserved
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
@@ -95,11 +89,9 @@ public class IncludePageSegment extends AbstractNamedAFPObject {
for (int i = 0; i < nameBytes.length; i++) {
data[9 + i] = nameBytes[i];
}
-
data[17] = x[0]; // x coordinate
data[18] = x[1];
data[19] = x[2];
-
data[20] = y[0]; // y coordinate
data[21] = y[1];
data[22] = y[2];
diff --git a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java b/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java
index f38096ade..f67ee8268 100644
--- a/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java
+++ b/src/java/org/apache/fop/render/afp/modca/InvokeMediumMap.java
@@ -34,30 +34,25 @@ public class InvokeMediumMap extends AbstractNamedAFPObject {
/**
* Constructor for the Invoke Medium Map
- * @param mediumMapName Name of the medium map
+ * @param name the name of the medium map
*/
- public InvokeMediumMap(String mediumMapName) {
-
- super(mediumMapName);
-
+ public InvokeMediumMap(String name) {
+ super(name);
}
/**
- * Accessor method to write the AFP datastream for the Invoke Medium Map
- * @param os The stream to write to
- * @throws java.io.IOException if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
+ public void writeDataStream(OutputStream os) throws IOException {
byte[] data = new byte[17];
data[0] = 0x5A;
// Set the total record length
- byte[] rl1 = BinaryUtils.convert(16, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
+ byte[] len = BinaryUtils.convert(16, 2); //Ignore first byte
+ data[1] = len[0];
+ data[2] = len[1];
// Structured field ID for a IPO
data[3] = (byte) 0xD3;
@@ -69,13 +64,8 @@ public class InvokeMediumMap extends AbstractNamedAFPObject {
data[8] = 0x00; // Reserved
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java
index 05d45dc2f..e83f04b78 100644
--- a/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java
+++ b/src/java/org/apache/fop/render/afp/modca/MapCodedFont.java
@@ -138,7 +138,6 @@ public class MapCodedFont extends AbstractAFPObject {
baos.write(0x5D);
baos.write(BinaryUtils.convert(fd.scale, 2));
}
-
}
byte[] data = baos.toByteArray();
@@ -149,7 +148,6 @@ public class MapCodedFont extends AbstractAFPObject {
data[2] = rl1[1];
os.write(data);
-
}
/**
diff --git a/src/java/org/apache/fop/render/afp/modca/MapDataResource.java b/src/java/org/apache/fop/render/afp/modca/MapDataResource.java
new file mode 100644
index 000000000..66ae57d75
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/MapDataResource.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Map Data Resource structured field specifies resources that are
+ * required for presentation.
+ */
+public class MapDataResource extends AbstractStructuredAFPObject {
+ /**
+ * Static default generated name reference
+ */
+ private static final String DEFAULT_NAME = "MDR00001";
+
+ /**
+ * Main constructor
+ * @param obj a map data resource for a given structured AFP object
+ */
+ public MapDataResource(AbstractStructuredAFPObject obj) {
+ String fqName = obj.getFullyQualifiedName();
+ if (fqName != null) {
+ super.setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_BEGIN_RESOURCE_OBJECT_REF,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR, fqName);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeStart(OutputStream os) throws IOException {
+ super.writeStart(os);
+
+ // RGLength
+ byte[] len = BinaryUtils.convert(8 + getTripletDataLength(), 2);
+ byte[] data = new byte[] {
+ 0x5A, // Structured field identifier
+ len[0], // Length byte 1
+ len[1], // Length byte 2
+ (byte) 0xD3, // Structured field id byte 1
+ (byte) 0xAB, // Structured field id byte 2
+ (byte) 0xC3, // Structured field id byte 3
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00 // Reserved
+ };
+ os.write(data);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java
index 129a3f5a1..65f90aa2b 100644
--- a/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java
+++ b/src/java/org/apache/fop/render/afp/modca/MapPageOverlay.java
@@ -36,15 +36,21 @@ public class MapPageOverlay extends AbstractAFPObject {
/**
* The collection of overlays (maximum of 254 stored as byte[])
*/
- private List overLays = new java.util.ArrayList();
+ private List overLays = null;
/**
* Constructor for the Map Page Overlay
*/
public MapPageOverlay() {
-
}
+ private List getOverlays() {
+ if (overLays == null) {
+ this.overLays = new java.util.ArrayList();
+ }
+ return this.overLays;
+ }
+
/**
* Add an overlay to to the map page overlay object.
*
@@ -53,23 +59,19 @@ public class MapPageOverlay extends AbstractAFPObject {
* @throws MaximumSizeExceededException if the maximum size is reached
*/
public void addOverlay(String name) throws MaximumSizeExceededException {
-
- if (overLays.size() > 253) {
+ if (getOverlays().size() > 253) {
throw new MaximumSizeExceededException();
}
-
if (name.length() != 8) {
throw new IllegalArgumentException("The name of overlay " + name
+ " must be 8 characters");
}
-
if (log.isDebugEnabled()) {
log.debug("addOverlay():: adding overlay " + name);
}
-
try {
byte[] data = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
- overLays.add(data);
+ getOverlays().add(data);
} catch (UnsupportedEncodingException usee) {
log.error("addOverlay():: UnsupportedEncodingException translating the name "
+ name);
@@ -82,7 +84,7 @@ public class MapPageOverlay extends AbstractAFPObject {
* @throws java.io.IOException if an I/O exception occurred
*/
public void writeDataStream(OutputStream os) throws IOException {
- int oLayCount = overLays.size();
+ int oLayCount = getOverlays().size();
int recordlength = oLayCount * 18;
byte[] data = new byte[recordlength + 9];
diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java b/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java
index 688288063..6ff3f03f8 100644
--- a/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java
+++ b/src/java/org/apache/fop/render/afp/modca/ObjectAreaPosition.java
@@ -55,7 +55,6 @@ public class ObjectAreaPosition extends AbstractAFPObject {
byte[] len = BinaryUtils.convert(32, 2);
byte[] xcoord = BinaryUtils.convert(x, 3);
byte[] ycoord = BinaryUtils.convert(y, 3);
-
byte[] data = new byte[] {
0x5A,
len[0], // Length
@@ -91,9 +90,6 @@ public class ObjectAreaPosition extends AbstractAFPObject {
0x00,
0x00, // RefCSys
};
-
os.write(data);
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java
index 27fe7c270..b2108d0d7 100644
--- a/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java
+++ b/src/java/org/apache/fop/render/afp/modca/ObjectEnvironmentGroup.java
@@ -34,7 +34,7 @@ import java.io.OutputStream;
* normally contained in the object environment group, or it may specify that one or
* more default values are to be used.
*/
-public final class ObjectEnvironmentGroup extends AbstractStructuredAFPObject {
+public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject {
/**
* Default name for the object environment group
@@ -150,7 +150,9 @@ public final class ObjectEnvironmentGroup extends AbstractStructuredAFPObject {
/**
* {@inheritDoc}
*/
- public void writeContent(OutputStream os) throws IOException {
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+
objectAreaDescriptor.writeDataStream(os);
objectAreaPosition.writeDataStream(os);
diff --git a/src/java/org/apache/fop/render/afp/modca/Overlay.java b/src/java/org/apache/fop/render/afp/modca/Overlay.java
index 628ef5516..e7d3b87d0 100644
--- a/src/java/org/apache/fop/render/afp/modca/Overlay.java
+++ b/src/java/org/apache/fop/render/afp/modca/Overlay.java
@@ -50,43 +50,14 @@ public class Overlay extends AbstractPageObject {
*/
public Overlay(String name, int width, int height, int rotation,
int widthResolution, int heightResolution) {
-
super(name, width, height, rotation, widthResolution, heightResolution);
-
}
/**
- * Accessor method to write the AFP datastream for the overlay.
- *
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- activeEnvironmentGroup.writeDataStream(os);
-
- writeObjectList(segments, os);
-
- writeObjectList(tagLogicalElements, os);
-
- writeObjectList(objects, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the overlay.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -96,26 +67,17 @@ public class Overlay extends AbstractPageObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the overlay.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -125,15 +87,9 @@ public class Overlay extends AbstractPageObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
}
diff --git a/src/java/org/apache/fop/render/afp/modca/PageGroup.java b/src/java/org/apache/fop/render/afp/modca/PageGroup.java
index 0b40a83c5..39d7920e6 100644
--- a/src/java/org/apache/fop/render/afp/modca/PageGroup.java
+++ b/src/java/org/apache/fop/render/afp/modca/PageGroup.java
@@ -18,9 +18,9 @@
/* $Id$ */
package org.apache.fop.render.afp.modca;
+
import java.io.IOException;
import java.io.OutputStream;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -34,17 +34,12 @@ import java.util.List;
*
* @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
*/
-public class PageGroup extends AbstractNamedAFPObject {
-
- /**
- * The pages contained within this group
- */
- private List objects = new ArrayList();
+public class PageGroup extends AbstractResourceEnvironmentGroupContainer {
/**
* The tag logical elements contained within this group
*/
- private List tagLogicalElements = new ArrayList();
+ private List tagLogicalElements = null;
/**
* The page state
@@ -58,32 +53,16 @@ public class PageGroup extends AbstractNamedAFPObject {
* the name of the page group
*/
public PageGroup(String name) {
-
super(name);
-
}
- /**
- * Adds a page object to the group.
- *
- * @param page
- * the page object to add
- */
- public void addPage(PageObject page) {
-
- if (!objects.contains(page)) {
- objects.add(page);
+ private List getTagLogicalElements() {
+ if (tagLogicalElements == null) {
+ this.tagLogicalElements = new java.util.ArrayList();
}
-
+ return this.tagLogicalElements;
}
-
- /**
- * @return the name of the page group
- */
- public String getName() {
- return name;
- }
-
+
/**
* Creates a TagLogicalElement on the page.
*
@@ -93,32 +72,17 @@ public class PageGroup extends AbstractNamedAFPObject {
* the value of the tag
*/
public void createTagLogicalElement(String name, String value) {
-
TagLogicalElement tle = new TagLogicalElement(name, value);
- tagLogicalElements.add(tle);
-
- }
-
- /**
- * Creates an InvokeMediaMap on the page.
- *
- * @param name
- * the name of the media map
- */
- public void createInvokeMediumMap(String name) {
-
- InvokeMediumMap imm = new InvokeMediumMap(name);
- objects.add(imm);
-
+ if (!getTagLogicalElements().contains(tle)) {
+ getTagLogicalElements().add(tle);
+ }
}
/**
* Method to mark the end of the page group.
*/
- public void endPageGroup() {
-
+ protected void endPageGroup() {
complete = true;
-
}
/**
@@ -129,33 +93,19 @@ public class PageGroup extends AbstractNamedAFPObject {
return complete;
}
- /**
- * Accessor method to write the AFP datastream for the page group.
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ /**
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(tagLogicalElements, os);
-
- writeObjectList(objects, os);
-
- writeEnd(os);
-
+ protected void writeContent(OutputStream os) throws IOException {
+ writeObjects(tagLogicalElements, os);
+ super.writeContent(os);
}
/**
- * Helper method to write the start of the page group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -165,26 +115,17 @@ public class PageGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the page group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -194,15 +135,9 @@ public class PageGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/PageObject.java b/src/java/org/apache/fop/render/afp/modca/PageObject.java
index a9a4581e7..bad80bcc1 100644
--- a/src/java/org/apache/fop/render/afp/modca/PageObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/PageObject.java
@@ -18,11 +18,10 @@
/* $Id$ */
package org.apache.fop.render.afp.modca;
+
import java.io.IOException;
import java.io.OutputStream;
-
-
/**
* Pages contain the data objects that comprise a presentation document. Each
* page has a set of data objects associated with it. Each page within a
@@ -46,11 +45,6 @@ import java.io.OutputStream;
public class PageObject extends AbstractPageObject {
/**
- * The resource group object
- */
- private ResourceGroup resourceGroup = null;
-
- /**
* Construct a new page object for the specified name argument, the page
* name should be an 8 character identifier.
*
@@ -69,20 +63,7 @@ public class PageObject extends AbstractPageObject {
*/
public PageObject(String name, int width, int height, int rotation,
int widthRes, int heightRes) {
-
super(name, width, height, rotation, widthRes, heightRes);
-
- }
-
- /**
- * Adds an overlay to the page resources
- * @param overlay the overlay to add
- */
- public void addOverlay(Overlay overlay) {
- if (resourceGroup == null) {
- resourceGroup = new ResourceGroup();
- }
- resourceGroup.addOverlay(overlay);
}
/**
@@ -98,47 +79,14 @@ public class PageObject extends AbstractPageObject {
* the orientation required for the overlay
*/
public void createIncludePageOverlay(String name, int x, int y, int orientation) {
-
- IncludePageOverlay ipo = new IncludePageOverlay(name, x, y, orientation);
- objects.add(ipo);
-
+ addObject(new IncludePageOverlay(name, x, y, orientation));
}
/**
- * Accessor method to write the AFP datastream for the page.
- * @param os The stream to write to
- * @throws java.io.IOException thrown if an I/O exception of some sort has occurred
+ * {@inheritDoc}
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (resourceGroup != null) {
- resourceGroup.writeDataStream(os);
- }
-
- activeEnvironmentGroup.writeDataStream(os);
-
- writeObjectList(segments, os);
-
- writeObjectList(tagLogicalElements, os);
-
- writeObjectList(objects, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the page.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -148,26 +96,17 @@ public class PageObject extends AbstractPageObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the page.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -177,15 +116,9 @@ public class PageObject extends AbstractPageObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/PageSegment.java b/src/java/org/apache/fop/render/afp/modca/PageSegment.java
new file mode 100644
index 000000000..f88e3cc55
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/PageSegment.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * A page segment is a MO:DCA-P resource object. It may be stored in an
+ * external resource library or it may be carried in a resource group.
+ * Page segments contain any combination of IOCA image objects and
+ * GOCA graphics objects.
+ */
+public class PageSegment extends AbstractNamedAFPObject {
+
+ private List objects = null;
+
+ /**
+ * Main constructor
+ * @param name the name of this object
+ */
+ public PageSegment(String name) {
+ super(name);
+ }
+
+ /**
+ * Adds a resource object (image/graphic) to this page segment
+ * @param object the resource objec to add to this page segment
+ */
+ public void addObject(AbstractAFPObject object) {
+ if (objects == null) {
+ objects = new java.util.ArrayList();
+ }
+ objects.add(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeStart(OutputStream os) throws IOException {
+ byte[] data = new byte[17];
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0x5F; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+ for (int i = 0; i < nameBytes.length; i++) {
+ data[9 + i] = nameBytes[i];
+ }
+ os.write(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeEnd(OutputStream os) throws IOException {
+ byte[] data = new byte[17];
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0x5F; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+ for (int i = 0; i < nameBytes.length; i++) {
+ data[9 + i] = nameBytes[i];
+ }
+ os.write(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os);
+ writeObjects(objects, os);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/PreprocessPresentationObject.java b/src/java/org/apache/fop/render/afp/modca/PreprocessPresentationObject.java
new file mode 100644
index 000000000..33e6407ee
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/PreprocessPresentationObject.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Preprocess Presentation Object structured field specifies presentation
+ * parameters for a data object that has been mapped as a resource.
+ */
+public class PreprocessPresentationObject extends AbstractStructuredAFPObject {
+ private static final byte TYPE_OTHER = (byte)0x92;
+ private static final byte TYPE_OVERLAY = (byte)0xDF;
+ private static final byte TYPE_IMAGE = (byte)0xFB;
+
+ private byte objType = TYPE_OTHER;
+ private byte objOrent = 0; // object always processed at 0 degree orientation
+ private int objXOffset = -1;
+ private int objYOffset = -1;
+
+ /**
+ * Main constructor
+ * @param prePresObj the presentation object to be preprocessed
+ */
+ public PreprocessPresentationObject(AbstractStructuredAFPObject prePresObj) {
+ if (prePresObj instanceof ImageObject || prePresObj instanceof Overlay) {
+ if (prePresObj instanceof ImageObject) {
+ this.objType = TYPE_IMAGE;
+ } else {
+ this.objType = TYPE_OVERLAY;
+ }
+ setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_BEGIN_RESOURCE_OBJECT_REF,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR,
+ prePresObj.getFullyQualifiedName());
+ } else {
+ this.objType = TYPE_OTHER;
+// Registry registry = Registry.getInstance();
+// Registry.Entry entry = registry.getEntry(compontentId);
+// entry.
+// setObjectClassification(objectClass, componentId)
+ }
+ }
+
+ public static final byte ORIENTATION_ZERO_DEGREES = 1;
+ public static final byte ORIENTATION_90_DEGREES = 2;
+ public static final byte ORIENTATION_180_DEGREES = 4;
+ public static final byte ORIENTATION_270_DEGREES = 8;
+
+ /**
+ * Sets the object orientations relative to media leading edge
+ * @param orientation the object orientations relative to media leading edge
+ */
+ public void setOrientation(byte orientation) {
+ objOrent = (byte)orientation;
+ }
+
+ /**
+ * Sets the X axis origin for object content
+ * @param xOffset the X axis origin for object content
+ */
+ public void setXOffset(int xOffset) {
+ this.objXOffset = xOffset;
+ }
+
+ /**
+ * Sets the Y axis origin for object content
+ * @param yOffset the Y axis origin for object content
+ */
+ public void setYOffset(int yOffset) {
+ this.objYOffset = yOffset;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeStart(OutputStream os) throws IOException {
+ super.writeStart(os);
+
+ byte[] l = BinaryUtils.convert(19 + getTripletDataLength(), 2);
+ byte[] data = new byte[9];
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = l[0]; // Length byte 1
+ data[2] = l[1]; // Length byte 1
+ data[3] = (byte)0xD3; // Structured field id byte 1
+ data[4] = (byte)0xAD; // Structured field id byte 2
+ data[5] = (byte)0xC3; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ os.write(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeContent(OutputStream os) throws IOException {
+ byte[] data = new byte[12];
+ byte[] l = BinaryUtils.convert(12 + getTripletDataLength(), 2);
+ data[0] = l[0]; // RGLength
+ data[1] = l[1]; // RGLength
+ data[2] = objType; // ObjType
+ data[3] = 0x00; // Reserved
+ data[4] = 0x00; // Reserved
+ data[5] = objOrent; // ObjOrent
+ if (objXOffset > 0) {
+ byte[] xOff = BinaryUtils.convert(objYOffset, 3);
+ data[6] = xOff[0]; // XocaOset (not specified)
+ data[7] = xOff[1]; // XocaOset
+ data[8] = xOff[2]; // XocaOset
+ } else {
+ data[6] = (byte)0xFF; // XocaOset (not specified)
+ data[7] = (byte)0xFF; // XocaOset
+ data[8] = (byte)0xFF; // XocaOset
+ }
+ if (objYOffset > 0) {
+ byte[] yOff = BinaryUtils.convert(objYOffset, 3);
+ data[9] = yOff[0]; // YocaOset (not specified)
+ data[10] = yOff[1]; // YocaOset
+ data[11] = yOff[2]; // YocaOset
+ } else {
+ data[9] = (byte)0xFF; // YocaOset (not specified)
+ data[10] = (byte)0xFF; // YocaOset
+ data[11] = (byte)0xFF; // YocaOset
+ }
+ os.write(data);
+
+ // Triplets
+ super.writeContent(os);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java
index 901f24bb1..49f7c81a8 100644
--- a/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java
+++ b/src/java/org/apache/fop/render/afp/modca/PresentationTextObject.java
@@ -22,7 +22,7 @@ package org.apache.fop.render.afp.modca;
import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.ArrayList;
+import java.util.List;
/**
* The Presentation Text object is the data object used in document processing
@@ -47,17 +47,15 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
*/
private static final String DEFAULT_NAME = "PTO00001";
- private PresentationTextData currentPresentationTextData = null;
+ private PresentationTextData currentPresentationTextData;
- private ArrayList presentationTextData = new ArrayList();
+ private List presentationTextData;
/**
* Default constructor for the PresentationTextObject
*/
public PresentationTextObject() {
-
this(DEFAULT_NAME);
-
}
/**
@@ -66,15 +64,13 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* @param name the name of this presentation object
*/
public PresentationTextObject(String name) {
-
super(name);
-
}
/**
* Create the presentation text data for the byte array of data.
*
- * @param fontNumber
+ * @param fontNum
* The font resource identifier.
* @param x
* The x coordinate for the text data.
@@ -89,18 +85,16 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* @param data
* The text data to be created.
*/
- public void createTextData(int fontNumber, int x, int y, Color col,
+ public void createTextData(int fontNum, int x, int y, Color col,
int vsci, int ica, byte[] data) {
-
// Use a default orientation of zero
- createTextData(fontNumber, x, y, 0, col, vsci, ica, data);
-
+ createTextData(fontNum, x, y, 0, col, vsci, ica, data);
}
/**
* Create the presentation text data for the byte array of data.
*
- * @param fontReference
+ * @param fontRef
* The font resource identifier.
* @param x
* The x coordinate for the text data.
@@ -117,25 +111,19 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* @param data
* The text data to be created.
*/
- public void createTextData(int fontReference, int x, int y, int orientation,
+ public void createTextData(int fontRef, int x, int y, int orientation,
Color col, int vsci, int ica, byte[] data) {
-
if (currentPresentationTextData == null) {
startPresentationTextData();
}
-
try {
- currentPresentationTextData.createTextData(fontReference, x, y,
+ currentPresentationTextData.createTextData(fontRef, x, y,
orientation, col, vsci, ica, data);
-
} catch (MaximumSizeExceededException msee) {
-
endPresentationTextData();
- createTextData(fontReference, x, y, orientation, col, vsci, ica, data);
-
+ createTextData(fontRef, x, y, orientation, col, vsci, ica, data);
}
-
}
/**
@@ -180,47 +168,38 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
*/
public void createLineData(int x1, int y1, int x2, int y2, int thickness,
int orientation, Color col) {
-
if (currentPresentationTextData == null) {
startPresentationTextData();
}
-
try {
-
currentPresentationTextData.createLineData(x1, y1, x2, y2,
thickness, orientation, col);
-
} catch (MaximumSizeExceededException msee) {
-
endPresentationTextData();
createLineData(x1, y1, x2, y2, thickness, orientation, col);
-
}
-
}
/**
* Helper method to mark the start of the presentation text data
*/
private void startPresentationTextData() {
-
+ if (presentationTextData == null) {
+ presentationTextData = new java.util.ArrayList();
+ }
if (presentationTextData.size() == 0) {
currentPresentationTextData = new PresentationTextData(true);
} else {
currentPresentationTextData = new PresentationTextData();
}
-
presentationTextData.add(currentPresentationTextData);
-
}
/**
* Helper method to mark the end of the presentation text data
*/
private void endPresentationTextData() {
-
currentPresentationTextData = null;
-
}
/**
@@ -228,15 +207,10 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* @param os The stream to write to
* @throws java.io.IOException thrown if an I/O exception of some sort has occurred
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
+ public void writeDataStream(OutputStream os) throws IOException {
writeStart(os);
-
- writeObjectList(presentationTextData, os);
-
+ writeObjects(presentationTextData, os);
writeEnd(os);
-
}
/**
@@ -244,20 +218,14 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* @return the name of this presentation text object
*/
public String getName() {
-
return name;
-
}
/**
- * Helper method to write the start of the presenation text object.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
-
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -267,27 +235,17 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the presenation text object.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -297,15 +255,10 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
@@ -316,22 +269,14 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
* method terminates the control sequence.
*/
public void endControlSequence() {
-
if (currentPresentationTextData == null) {
startPresentationTextData();
}
-
try {
-
currentPresentationTextData.endControlSequence();
-
} catch (MaximumSizeExceededException msee) {
-
endPresentationTextData();
endControlSequence();
-
}
-
}
-
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/Registry.java b/src/java/org/apache/fop/render/afp/modca/Registry.java
new file mode 100644
index 000000000..b643cd2d2
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/Registry.java
@@ -0,0 +1,353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * MOD:CA object type registry
+ */
+public final class Registry {
+
+ /** IOB supported object types */
+ public static final byte IOCA_FS10 = 5;
+ public static final byte IOCA_FS11 = 11;
+ public static final byte IOCA_FS45 = 12;
+ public static final byte DIB_WIN = 17; //device independent bitmap
+ public static final byte DIB_OS2 = 18;
+ public static final byte PCX = 19;
+ public static final byte GIF = 22;
+ public static final byte JFIF = 23; // jpeg file interchange format
+ public static final byte PDF_SINGLE_PAGE = 25;
+ public static final byte PCL_PAGE_OBJECT = 34;
+ public static final byte EPS_TRANS = 48;
+ public static final byte PDF_SINGLE_PAGE_TRANS = 49;
+ public static final byte JPEG2000 = 58;
+
+ /** IOB unsupported object types */
+ public static final byte EPS = 13;
+ public static final byte TIFF = 14;
+ public static final byte COM_SETUP_FILE = 15;
+ public static final byte TAPE_LABEL_SETUP_FILE = 16;
+ public static final byte CMT = 20; // color mapping table
+ public static final byte ANACOMP_CONTROL_RECORD = 24;
+ public static final byte PDF_RESOURCE_OBJECT = 26;
+ public static final byte IOCA_FS42 = 45;
+ public static final byte RESIDENT_COLOR_PROFILE = 46;
+ public static final byte IOCA_FS45_TILE_RESOURCE = 47;
+ public static final byte FONT = 51;
+ public static final byte FONT_COLLECTION = 53;
+ public static final byte RESOURCE_ACCESS_TABLE = 54;
+ public static final byte IOCA_FS40 = 55;
+ public static final byte UP3I_PRINT_DATA = 56;
+ public static final byte COLOR_MANAGEMENT_RESOURCE = 57;
+
+
+ /** internal mapping array references */
+ private static final int COMPONENT_ID = 0;
+ private static final int OBJECT_TYPE_NAME = 1;
+ private static final int OBJECT_ID = 2;
+ private static final int CAN_BE_INCLUDED = 3;
+
+ private byte[][][] componentIdMap;
+
+ private static Registry instance = null;
+
+ /**
+ * @return a single instance of Registry
+ */
+ public static Registry getInstance() {
+ synchronized (instance) {
+ if (instance == null) {
+ instance = new Registry();
+ }
+ }
+ return instance;
+ }
+
+ private Registry() {
+ init();
+ }
+
+ private void init() {
+ try {
+ componentIdMap = new byte[][][] {
+ /* object type id (OID), object type name, compontent Id, can be included with IOB?, */
+ {
+ {IOCA_FS10},
+ "IOCA FS10".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x05},
+ {1}
+ },
+ {
+ {IOCA_FS11},
+ "IOCA FS11".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0B},
+ {1}
+ },
+ {
+ {IOCA_FS45},
+ "IOCA FS45".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0C},
+ {1}
+ },
+ {
+ {EPS},
+ "Encapsulated Postscript".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0D},
+ {0}
+ },
+ {
+ {TIFF},
+ "TIFF".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0E},
+ {0}
+ },
+ {
+ {COM_SETUP_FILE},
+ "COM setup".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x0F},
+ {0}
+ },
+ {
+ {TAPE_LABEL_SETUP_FILE},
+ "Tape Label setup".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x10},
+ {0}
+ },
+ {
+ {DIB_WIN},
+ "DIB, Windows Version".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x11},
+ {1}
+ },
+ {
+ {DIB_OS2},
+ "DIB, OS/2 PM Version".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x12},
+ {1}
+ },
+ {
+ {PCX},
+ "PCX".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x13},
+ {1}
+ },
+ {
+ {CMT},
+ "Color Mapping Table (CMT)".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x14},
+ {0}
+ },
+ {
+ {GIF},
+ "GIF".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x16},
+ {1}
+ },
+ {
+ {JFIF},
+ "JFIF".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x17},
+ {1}
+ },
+ {
+ {ANACOMP_CONTROL_RECORD},
+ "AnaStak Control Record".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x18},
+ {0}
+ },
+ {
+ {PDF_SINGLE_PAGE},
+ "PDF Single-page Object".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x19},
+ {1}
+ },
+ {
+ {PDF_RESOURCE_OBJECT},
+ "PDF Resource Object".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x1A},
+ {0}
+ },
+ {
+ {PCL_PAGE_OBJECT},
+ "PCL Page Object".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x22},
+ {1}
+ },
+ {
+ {IOCA_FS42},
+ "IOCA FS42".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x2D},
+ {0}
+ },
+ {
+ {RESIDENT_COLOR_PROFILE},
+ "Resident Color Profile".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x2E},
+ {0}
+ },
+ {
+ {IOCA_FS45_TILE_RESOURCE},
+ "IOCA FS45".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x2E},
+ {0}
+ },
+ {
+ {EPS_TRANS},
+ "EPS with Transparency".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x30},
+ {1}
+ },
+ {
+ {PDF_SINGLE_PAGE_TRANS},
+ "PDF with Transparency".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x31},
+ {1}
+ },
+ {
+ {FONT},
+ "TrueType/OpenType Font".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x33},
+ {0}
+ },
+ {
+ {FONT_COLLECTION},
+ "TrueType/OpenType Font Collection".getBytes(
+ AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x35},
+ {0}
+ },
+ {
+ {RESOURCE_ACCESS_TABLE},
+ "Resource Access Table".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x36},
+ {0}
+ },
+ {
+ {IOCA_FS40},
+ "IOCA FS40".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x37},
+ {0}
+ },
+ {
+ {UP3I_PRINT_DATA},
+ "IP3i Print Data".getBytes(AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x38},
+ {0}
+ },
+ {
+ {COLOR_MANAGEMENT_RESOURCE},
+ "Color Management Resource (CMR)".getBytes(
+ AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x39},
+ {0}
+ },
+ {
+ {JPEG2000},
+ "JPEG2000 (JP2) File Format".getBytes(
+ AFPConstants.EBCIDIC_ENCODING),
+ {0x06, 0x07, 0x2B, 0x12, 0x00, 0x04, 0x01, 0x01, 0x3A},
+ {1}
+ }
+ };
+ } catch (UnsupportedEncodingException e) {
+ // should never happen!
+ LogFactory.getLog("org.apache.fop.render.afp.modca.Registry").error(e.getMessage());
+ }
+ }
+
+ private byte[][][] getComponentIdMap() {
+ if (componentIdMap == null) {
+ init();
+ }
+ return componentIdMap;
+ }
+
+ private byte[][] getMapData(byte compontentId) {
+ getComponentIdMap();
+ for (int i = 0; i < componentIdMap.length; i++) {
+ if (compontentId == componentIdMap[i][0][0]) {
+ return componentIdMap[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns a registry Entry for a given componentId
+ * @param compontentId a compontent id
+ * @return the registry entry for a give componentId
+ */
+ public Entry getEntry(byte compontentId) {
+ byte[][] data = getMapData(compontentId);
+ if (data != null) {
+ return new Registry.Entry(data);
+ }
+ return null;
+ }
+
+ /**
+ * Encapsulates a MOD:CA Registry Entry
+ */
+ public final class Entry {
+ private byte[][] data;
+
+ /**
+ * Main constructor
+ * @param the map data structure array
+ */
+ private Entry(byte[][] data) {
+ this.data = data;
+ }
+
+ /**
+ * Returns a MOD:CA object type OID from a given a componentId
+ * @return the corresponding object type id for a given component id
+ * or null if the component id is unknown and the object type OID was not found.
+ */
+ public byte[] getOID() {
+ return data[OBJECT_ID];
+ }
+
+ /**
+ * @return the object type name for the given componentId
+ */
+ public byte[] getObjectTypeName() {
+ return data[OBJECT_TYPE_NAME];
+ }
+
+ /**
+ * @return the compontentId for this entry
+ */
+ public byte[] getComponentId() {
+ return data[COMPONENT_ID];
+ }
+
+ /**
+ * @return true if this component can be included with an IOB structured field
+ */
+ public boolean canBeIncluded() {
+ return data[CAN_BE_INCLUDED][0] == 1;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceEnvironmentGroup.java b/src/java/org/apache/fop/render/afp/modca/ResourceEnvironmentGroup.java
new file mode 100644
index 000000000..080226e9f
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/ResourceEnvironmentGroup.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * 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
+ */
+ private static final String DEFAULT_NAME = "REG00001";
+
+ /**
+ * The maps data resources contained in this resource environment group
+ */
+ private List mapDataResources = null;
+
+ /**
+ * 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
+ */
+ private List preProcessPresentationObjects = null;
+
+ /**
+ * The resource environment group state
+ */
+ private boolean complete = false;
+
+ /**
+ * Default constructor
+ */
+ public ResourceEnvironmentGroup() {
+ this(DEFAULT_NAME);
+ }
+
+ private List getMapDataResources() {
+ if (mapDataResources == null) {
+ this.mapDataResources = new java.util.ArrayList();
+ }
+ return this.mapDataResources;
+ }
+
+ private List getMapPageOverlays() {
+ if (mapPageOverlays == null) {
+ this.mapPageOverlays = new java.util.ArrayList();
+ }
+ return this.mapPageOverlays;
+ }
+
+ private List getPreprocessPresentationObjects() {
+ if (preProcessPresentationObjects == null) {
+ this.preProcessPresentationObjects = new java.util.ArrayList();
+ }
+ return this.preProcessPresentationObjects;
+ }
+
+ /**
+ * Constructor for the ResourceEnvironmentGroup, this takes a
+ * name parameter which must be 8 characters long.
+ * @param name the resource environment group name
+ */
+ public ResourceEnvironmentGroup(String name) {
+ super(name);
+ }
+
+ /**
+ * Adds an AFP object mapping reference to this resource environment group
+ * @param obj the object to add
+ */
+ public void addObject(AbstractStructuredAFPObject obj) {
+ getMapDataResources().add(new MapDataResource(obj));
+ 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];
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xD9; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+ for (int i = 0; i < nameBytes.length; i++) {
+ data[9 + i] = nameBytes[i];
+ }
+ os.write(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ writeObjects(mapDataResources, os);
+ writeObjects(mapPageOverlays, os);
+ writeObjects(preProcessPresentationObjects, os);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeEnd(OutputStream os) throws IOException {
+ byte[] data = new byte[17];
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xD9; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+ for (int i = 0; i < nameBytes.length; i++) {
+ data[9 + i] = nameBytes[i];
+ }
+ os.write(data);
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java
index 07043dcf1..48f4f0eeb 100644
--- a/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java
+++ b/src/java/org/apache/fop/render/afp/modca/ResourceGroup.java
@@ -21,32 +21,34 @@ package org.apache.fop.render.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
+
+import org.apache.fop.render.afp.DataObjectParameters;
+import org.apache.fop.render.afp.ImageObjectParameters;
+import org.apache.fop.render.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.render.afp.tools.StringUtils;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
/**
* A Resource Group contains a set of overlays.
*/
public final class ResourceGroup extends AbstractNamedAFPObject {
-
+
/**
* Default name for the resource group
*/
private static final String DEFAULT_NAME = "RG000001";
-
/**
- * The overlays contained in this resource group
+ * Mapping of resource uri to data resource object (image/graphic)
*/
- private List overlays = new ArrayList();
+ private Map/*<String,AbstractAFPObject>*/ resourceMap = null;
/**
* Default constructor
*/
public ResourceGroup() {
-
this(DEFAULT_NAME);
-
}
/**
@@ -55,53 +57,208 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
* @param name the resource group name
*/
public ResourceGroup(String name) {
-
super(name);
-
}
+ private static final String IMAGE_NAME_PREFIX = "IMG";
+ private static final String GRAPHIC_NAME_PREFIX = "GRA";
+ private static final String PAGE_SEGMENT_NAME_PREFIX = "PAG";
+ private static final String BARCODE_NAME_PREFIX = "BAR";
+ private static final String OTHER_NAME_PREFIX = "OTH";
+
/**
- * Adds an overlay to the resource group
- * @param overlay the overlay to add
+ * Converts a byte array containing 24 bit RGB image data to a grayscale
+ * image.
+ *
+ * @param io
+ * the target image object
+ * @param raw
+ * the buffer containing the RGB image data
+ * @param width
+ * the width of the image in pixels
+ * @param height
+ * the height of the image in pixels
+ * @param bitsPerPixel
+ * the number of bits to use per pixel
*/
- public void addOverlay(Overlay overlay) {
- overlays.add(overlay);
+ private static void convertToGrayScaleImage(ImageObject io, byte[] raw, int width,
+ int height, int bitsPerPixel) {
+ int pixelsPerByte = 8 / bitsPerPixel;
+ int bytewidth = (width / pixelsPerByte);
+ if ((width % pixelsPerByte) != 0) {
+ bytewidth++;
+ }
+ byte[] bw = new byte[height * bytewidth];
+ byte ib;
+ for (int y = 0; y < height; y++) {
+ ib = 0;
+ int i = 3 * y * width;
+ for (int x = 0; x < width; x++, i += 3) {
+
+ // see http://www.jguru.com/faq/view.jsp?EID=221919
+ double greyVal = 0.212671d * ((int) raw[i] & 0xff) + 0.715160d
+ * ((int) raw[i + 1] & 0xff) + 0.072169d
+ * ((int) raw[i + 2] & 0xff);
+ switch (bitsPerPixel) {
+ case 1:
+ if (greyVal < 128) {
+ ib |= (byte) (1 << (7 - (x % 8)));
+ }
+ break;
+ case 4:
+ greyVal /= 16;
+ ib |= (byte) ((byte) greyVal << ((1 - (x % 2)) * 4));
+ break;
+ case 8:
+ ib = (byte) greyVal;
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ "Unsupported bits per pixel: " + bitsPerPixel);
+ }
+
+ if ((x % pixelsPerByte) == (pixelsPerByte - 1)
+ || ((x + 1) == width)) {
+ bw[(y * bytewidth) + (x / pixelsPerByte)] = ib;
+ ib = 0;
+ }
+ }
+ }
+ io.setImageIDESize((byte) bitsPerPixel);
+ io.setImageData(bw);
}
/**
- * Returns the list of overlays
- * @return the list of overlays
+ * Helper method to create an image on the current container and to return
+ * the object.
+ * @param params the set of image object parameters
+ * @return a newly created image object
*/
- public List getOverlays() {
- return overlays;
+ private ImageObject createImage(ImageObjectParameters params) {
+ String name = IMAGE_NAME_PREFIX
+ + StringUtils.lpad(String.valueOf(getResourceCount() + 1), '0', 5);
+ ImageObject imageObj = new ImageObject(name);
+ if (params.hasCompression()) {
+ int compression = params.getCompression();
+ switch (compression) {
+ case TIFFImage.COMP_FAX_G3_1D:
+ imageObj.setImageEncoding(ImageContent.COMPID_G3_MH);
+ break;
+ case TIFFImage.COMP_FAX_G3_2D:
+ imageObj.setImageEncoding(ImageContent.COMPID_G3_MR);
+ break;
+ case TIFFImage.COMP_FAX_G4_2D:
+ imageObj.setImageEncoding(ImageContent.COMPID_G3_MMR);
+ break;
+ default:
+ throw new IllegalStateException(
+ "Invalid compression scheme: " + compression);
+ }
+ }
+ imageObj.setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_BEGIN_RESOURCE_OBJECT_REF,
+ FullyQualifiedNameTriplet.FORMAT_URL, params.getUri());
+ imageObj.setImageParameters(params.getWidthRes(), params.getHeightRes(),
+ params.getImageDataWidth(), params.getImageDataHeight());
+ if (params.isColor()) {
+ imageObj.setImageIDESize((byte)24);
+ imageObj.setImageData(params.getData());
+ } else {
+ convertToGrayScaleImage(imageObj, params.getData(),
+ params.getImageDataWidth(), params.getImageDataHeight(),
+ params.getBitsPerPixel());
+ }
+ return imageObj;
}
-
+
/**
- * Accessor method to obtain write the AFP datastream for
- * the resource group.
- * @param os The stream to write to
- * @throws java.io.IOException if an I/O exception of some sort has occurred
+ * Helper method to create a graphic in the current container and to return
+ * the object.
+ * @param params the data object parameters
+ * @return a newly created graphics object
*/
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(overlays, os);
-
- writeEnd(os);
+ private GraphicsObject createGraphic(DataObjectParameters params) {
+ String name = GRAPHIC_NAME_PREFIX
+ + StringUtils.lpad(String.valueOf(getResourceCount() + 1), '0', 5);
+ GraphicsObject graphicsObj = new GraphicsObject(name);
+ return graphicsObj;
+ }
+ /**
+ * Adds a data object to this resource group
+ * @param params the data object parameters
+ * @return an include object reference
+ */
+ public IncludeObject addObject(DataObjectParameters params) {
+ ResourceObject resourceObj = (ResourceObject)getResourceMap().get(params.getUri());
+ if (resourceObj == null) {
+ AbstractDataObject dataObj;
+ if (params instanceof ImageObjectParameters) {
+ dataObj = createImage((ImageObjectParameters)params);
+ } else {
+ dataObj = createGraphic(params);
+ }
+ // TODO: AC - rotation?
+ int rotation = 0;
+ dataObj.setViewport(params.getX(), params.getY(),
+ params.getWidth(), params.getHeight(),
+ params.getWidthRes(), params.getHeightRes(), rotation);
+
+ // Wrap the data object in a resource object
+ resourceObj = new ResourceObject(dataObj.getName(), dataObj);
+ getResourceMap().put(params.getUri(), resourceObj);
+ }
+ IncludeObject includeObj = new IncludeObject(resourceObj);
+ //includeObj.setObjectAreaSize(params.getX(), params.getY());
+ return includeObj;
+ }
+
+ /**
+ * @return the number of resources contained in this resource group
+ */
+ public int getResourceCount() {
+ if (resourceMap != null) {
+ return resourceMap.size();
+ }
+ return 0;
+ }
+
+ /**
+ * Returns true if the resource exists within this resource group,
+ * false otherwise.
+ *
+ * @param uri the uri of the resource
+ * @return true if the resource exists within this resource group
+ */
+ public boolean resourceExists(String uri) {
+ return getResourceMap().containsKey(uri);
+ }
+
+ /**
+ * Returns the list of resources
+ * @return the list of resources
+ */
+ public Map/*<String,AbstractAFPObject>*/ getResourceMap() {
+ if (resourceMap == null) {
+ resourceMap = new java.util.HashMap/*<String,AbstractAFPObject>*/();
+ }
+ return resourceMap;
}
/**
- * Helper method to write the start of the resource group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeStart(OutputStream os)
- throws IOException {
+ public void writeContent(OutputStream os) throws IOException {
+ if (resourceMap != null) {
+ super.writeObjects(resourceMap.values(), os);
+ }
+ }
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeStart(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -111,26 +268,17 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
/**
- * Helper method to write the end of the resource group.
- * @param os The stream to write to
+ * {@inheritDoc}
*/
- private void writeEnd(OutputStream os)
- throws IOException {
-
+ protected void writeEnd(OutputStream os) throws IOException {
byte[] data = new byte[17];
-
data[0] = 0x5A; // Structured field identifier
data[1] = 0x00; // Length byte 1
data[2] = 0x10; // Length byte 2
@@ -140,15 +288,16 @@ public final class ResourceGroup extends AbstractNamedAFPObject {
data[6] = 0x00; // Flags
data[7] = 0x00; // Reserved
data[8] = 0x00; // Reserved
-
for (int i = 0; i < nameBytes.length; i++) {
-
data[9 + i] = nameBytes[i];
-
}
-
os.write(data);
-
}
-
-} \ No newline at end of file
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return this.name + " " + this.resourceMap;
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/ResourceObject.java b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java
new file mode 100644
index 000000000..ff660a208
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/ResourceObject.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.render.afp.modca.triplets.Triplet;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * This resource structured field begins an envelope that is used to carry
+ * resource objects in print-file-level (external) resource groups.
+ */
+public class ResourceObject extends AbstractPreparedAFPObject {
+
+ /**
+ * Resource object types
+ */
+ private static final byte GRAPHICS_OBJECT = 0x03;
+ private static final byte BARCODE_OBJECT = 0x05;
+ private static final byte IMAGE_OBJECT = 0x06;
+ private static final byte FONT_CHARACTER_SET_OBJECT = 0x40;
+ private static final byte CODE_PAGE_OBJECT = 0x41;
+ private static final byte CODED_FONT_OBJECT = 0x42;
+ private static final byte OBJECT_CONTAINER = (byte) 0x92;
+ private static final byte DOCUMENT_OBJECT = (byte) 0xA8;
+ private static final byte PAGE_SEGMENT_OBJECT = (byte) 0xFB;
+ private static final byte OVERLAY_OBJECT = (byte) 0xFC;
+ private static final byte PAGEDEF_OBJECT = (byte) 0xFD;
+ private static final byte FORMDEF_OBJECT = (byte) 0xFE;
+
+ /**
+ * the resource object
+ */
+ private AbstractNamedAFPObject resourceObj = null;
+
+ /**
+ * Default constructor
+ *
+ * @param name the name of this resource (reference id)
+ * @param resourceObj the resource object to be added
+ */
+ public ResourceObject(String name, AbstractNamedAFPObject resourceObj) {
+ super(name);
+ this.resourceObj = resourceObj;
+ byte type;
+ if (resourceObj instanceof ImageObject) {
+ type = IMAGE_OBJECT;
+ } else if (resourceObj instanceof GraphicsObject) {
+ type = GRAPHICS_OBJECT;
+ } else if (resourceObj instanceof Document) {
+ type = DOCUMENT_OBJECT;
+ } else if (resourceObj instanceof PageSegment) {
+ type = PAGE_SEGMENT_OBJECT;
+ } else if (resourceObj instanceof Overlay) {
+ type = OVERLAY_OBJECT;
+ } else {
+ throw new UnsupportedOperationException(
+ "Unsupported resource object type " + resourceObj);
+ }
+ setResourceObjectType(type);
+ }
+
+ private void setResourceObjectType(byte type) {
+ getTriplets().add(new ResourceObjectTypeTriplet(type));
+ }
+
+ /**
+ * @return the resource object contained in this envelope
+ */
+ public AbstractNamedAFPObject getResource() {
+ return this.resourceObj;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeStart(OutputStream os) throws IOException {
+ super.writeStart(os);
+
+ // Set the total record length
+ byte[] len = BinaryUtils.convert(18 + getTripletDataLength(), 2);
+ byte[] data = new byte[] {
+ 0x5A, // Structured field identifier
+ len[0], // Length byte 1
+ len[1], // Length byte 2
+ (byte)0xD3, // Structured field id byte 1
+ (byte)0xA8, // Structured field id byte 2
+ (byte)0xCE, // Structured field id byte 3
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ nameBytes[0],
+ nameBytes[1],
+ nameBytes[2],
+ nameBytes[3],
+ nameBytes[4],
+ nameBytes[5],
+ nameBytes[6],
+ nameBytes[7],
+ 0x00, // Reserved
+ 0x00, // Reserved
+ };
+ os.write(data);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ super.writeContent(os); // write triplets
+ if (resourceObj != null) {
+ resourceObj.writeDataStream(os);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeEnd(OutputStream os) throws IOException {
+ byte[] data = new byte[] {
+ 0x5A, // Structured field identifier
+ 0x00, // Length byte 1
+ 0x10, // Length byte 2
+ (byte)0xD3, // Structured field id byte 1
+ (byte)0xA9, // Structured field id byte 2
+ (byte)0xCE, // Structured field id byte 3
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ nameBytes[0],
+ nameBytes[1],
+ nameBytes[2],
+ nameBytes[3],
+ nameBytes[4],
+ nameBytes[5],
+ nameBytes[6],
+ nameBytes[7],
+ };
+ os.write(data);
+ }
+
+ private class ResourceObjectTypeTriplet extends Triplet {
+
+ private static final byte RESOURCE_OBJECT = 0x21;
+
+ /**
+ * Main constructor
+ *
+ * @param type
+ * the resource type
+ */
+ public ResourceObjectTypeTriplet(byte type) {
+ super(RESOURCE_OBJECT,
+ new byte[] {
+ type,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ }
+ );
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java
new file mode 100644
index 000000000..23c0d7e6b
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/FullyQualifiedNameTriplet.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+package org.apache.fop.render.afp.modca.triplets;
+
+
+/**
+ * A Fully Qualified Name triplet enable the identification and referencing of
+ * objects using Gloabl Identifiers (GIDs).
+ */
+public class FullyQualifiedNameTriplet extends Triplet {
+ // Specifies how the GID will be used
+ public static final byte TYPE_REPLACE_FIRST_GID_NAME = 0x01;
+ public static final byte TYPE_FONT_FAMILY_NAME = 0x07;
+ public static final byte TYPE_FONT_TYPEFACE_NAME = 0x08;
+ public static final byte TYPE_MODCA_RESOURCE_HIERARCHY_REF = 0x09;
+ public static final byte TYPE_BEGIN_RESOURCE_GROUP_REF = 0x0A;
+ public static final byte TYPE_ATTRIBUTE_GID = 0x0B;
+ public static final byte TYPE_PROCESS_ELEMENT_GID = 0x0C;
+ public static final byte TYPE_BEGIN_PAGE_GROUP_REF = 0x0D;
+ public static final byte TYPE_MEDIA_TYPE_REF = 0x11;
+ public static final byte TYPE_COLOR_MANAGEMENT_RESOURCE_REF = 0x41;
+ public static final byte TYPE_DATA_OBJECT_FONT_BASE_FONT_ID = 0x6E;
+ public static final byte TYPE_DATA_OBJECT_FONT_LINKED_FONT_ID = 0x7E;
+ public static final byte TYPE_BEGIN_DOCUMENT_REF = (byte)0x83;
+ public static final byte TYPE_BEGIN_RESOURCE_OBJECT_REF = (byte)0x84;
+ public static final byte TYPE_CODE_PAGE_NAME_REF = (byte)0x85;
+ public static final byte TYPE_FONT_CHARSET_NAME_REF = (byte)0x86;
+ public static final byte TYPE_BEGIN_PAGE_REF = (byte)0x87;
+ public static final byte TYPE_BEGIN_MEDIUM_MAP_REF = (byte)0x8D;
+ public static final byte TYPE_CODED_FONT_NAME_REF = (byte)0x8E;
+ public static final byte TYPE_BEGIN_DOCUMENT_INDEX_REF = (byte)0x98;
+ public static final byte TYPE_BEGIN_OVERLAY_REF = (byte)0xB0;
+ public static final byte TYPE_DATA_OBJECT_INTERNAL_RESOURCE_REF = (byte)0xBE;
+ public static final byte TYPE_INDEX_ELEMENT_GID = (byte)0xCA;
+ public static final byte TYPE_OTHER_OBJECT_DATA_REF = (byte)0xCE;
+ public static final byte TYPE_DATA_OBJECT_EXTERNAL_RESOURCE_REF = (byte)0xDE;
+
+ // GID Format
+ public static final byte FORMAT_CHARSTR = (byte)0x00;
+ public static final byte FORMAT_OID = (byte)0x10;
+ public static final byte FORMAT_URL = (byte)0x20;
+
+ private byte[] fqName;
+
+ /**
+ * @return the actual fully qualified name of this triplet
+ */
+ public byte[] getFullyQualifiedName() {
+ return fqName;
+ }
+
+ /**
+ * Main constructor
+ * @param fqnType the fully qualified name type
+ * @param fqnFmt the fully qualified name format
+ * @param fqName the fully qualified name
+ */
+ public FullyQualifiedNameTriplet(byte fqnType, byte fqnFmt, byte[] fqName) {
+ super(FULLY_QUALIFIED_NAME);
+ this.fqName = fqName;
+ super.data = new byte[2 + fqName.length];
+ data[0] = fqnType;
+ data[1] = fqnFmt;
+ // FQName
+ System.arraycopy(fqName, 0, data, 2, fqName.length);
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/MeasurementUnitsTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/MeasurementUnitsTriplet.java
new file mode 100644
index 000000000..e99045292
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/MeasurementUnitsTriplet.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca.triplets;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Measurement Units triplet is used to specify the units of measure
+ * for a presentation space
+ */
+public class MeasurementUnitsTriplet extends Triplet {
+
+ private static final byte TEN_INCHES = 0x00;
+ private static final byte TEN_CM = 0x01;
+
+ /**
+ * Main constructor
+ */
+ public MeasurementUnitsTriplet() {
+ super(MEASUREMENT_UNITS);
+ //TODO: units correct?
+ byte[] xUnits = BinaryUtils.convert(1, 2);
+ byte[] yUnits = BinaryUtils.convert(1, 2);
+ super.data = new byte[] {
+ TEN_INCHES, // XoaBase
+ TEN_INCHES, // YoaBase
+ xUnits[0], // XoaUnits (x units per unit base)
+ xUnits[1],
+ yUnits[0], // YoaUnits (y units per unit base)
+ yUnits[1]
+ };
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectAreaSizeTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectAreaSizeTriplet.java
new file mode 100644
index 000000000..bd026763d
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectAreaSizeTriplet.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca.triplets;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Object Area Size triplet is used to specify the extent of an object area
+ * in the X and Y directions
+ */
+public class ObjectAreaSizeTriplet extends Triplet {
+
+ /**
+ * Main constructor
+ * @param x the object area extent for the X axis
+ * @param y the object area extent for the Y axis
+ */
+ public ObjectAreaSizeTriplet(int x, int y) {
+ super(Triplet.OBJECT_AREA_SIZE);
+ byte[] xOASize = BinaryUtils.convert(x, 3);
+ byte[] yOASize = BinaryUtils.convert(y, 3);
+ super.data = new byte[] {
+ 0x02, // SizeType
+ xOASize[0], // XoaSize - Object area extent for X axis
+ xOASize[1],
+ xOASize[2],
+ yOASize[0], // YoaSize - Object area extent for Y axis
+ yOASize[1],
+ yOASize[2]
+ };
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java
new file mode 100644
index 000000000..4d5f41359
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/ObjectClassificationTriplet.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca.triplets;
+
+import org.apache.fop.render.afp.modca.Registry;
+
+/**
+ * The Object Classification is used to classify and identify object data.
+ * The object data may or may not be defined by an IBM presentation architecture
+ */
+public class ObjectClassificationTriplet extends Triplet {
+ public static final byte CLASS_TIME_INVARIANT_PAGINATED_PRESENTATION_OBJECT = 0x01;
+ public static final byte CLASS_TIME_VARIANT_PRESENTATION_OBJECT = 0x10;
+ public static final byte CLASS_EXECUTABLE_PROGRAM = 0x20;
+ public static final byte CLASS_SETUP_FILE = 0x30;
+ public static final byte CLASS_SECONDARY_RESOURCE = 0x40;
+ public static final byte CLASS_DATA_OBJECT_FONT = 0x41;
+
+ /**
+ * Main constructor
+ *
+ * @param objectClass
+ * the object class type
+ * @param componentId
+ * the object componentId
+ */
+ public ObjectClassificationTriplet(byte objectClass, byte componentId) {
+ super(OBJECT_CLASSIFICATION);
+ byte[] data = new byte[93];
+ data[0] = 0x00; // reserved (must be zero)
+ data[1] = objectClass; // ObjClass
+ data[2] = 0x00; // reserved (must be zero)
+ data[3] = 0x00; // reserved (must be zero)
+ data[4] = 0x00; // StrucFlgs - Information on the structure of the object container
+ data[5] = 0x00; // StrucFlgs
+
+ Registry.Entry entry = Registry.getInstance().getEntry(componentId);
+
+ if (entry == null) {
+ throw new UnsupportedOperationException("unknown registry entry " + componentId);
+ }
+ // RegObjId - MOD:CA-registered ASN.1 OID for object type (8-23)
+ System.arraycopy(entry.getOID(), 0, data, 6, entry.getOID().length);
+
+ // ObjTpName - name of object type (24-55)
+ System.arraycopy(entry.getObjectTypeName(), 0, data, 22,
+ entry.getObjectTypeName().length);
+
+ // ObjLev (not specified) - Release level or version number of object type (56-63)
+
+ // CompName (not specified) - Name of company or org that owns object definition (64-95)
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/ResourceObjectTypeTriplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/ResourceObjectTypeTriplet.java
new file mode 100644
index 000000000..c157659d6
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/ResourceObjectTypeTriplet.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca.triplets;
+
diff --git a/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java
new file mode 100644
index 000000000..bcf6f22c3
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/triplets/Triplet.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.render.afp.modca.triplets;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.modca.AbstractAFPObject;
+
+/**
+ * A simple implementation of a MOD:CA triplet
+ */
+public class Triplet extends AbstractAFPObject {
+ public static final byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01;
+ public static final byte FULLY_QUALIFIED_NAME = 0x02;
+ public static final byte MAPPING_OPTION = 0x04;
+ public static final byte OBJECT_CLASSIFICATION = 0x10;
+ public static final byte MODCA_INTERCHANGE_SET = 0x18;
+ public static final byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F;
+ public static final byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21;
+ public static final byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22;
+ public static final byte RESOURCE_LOCAL_IDENTIFIER = 0x24;
+ public static final byte RESOURCE_SECTION_NUMBER = 0x25;
+ public static final byte CHARACTER_ROTATION = 0x26;
+ public static final byte OBJECT_BYTE_OFFSET = 0x2D;
+ public static final byte ATTRIBUTE_VALUE = 0x36;
+ public static final byte DESCRIPTOR_POSITION = 0x43;
+ public static final byte MEDIA_EJECT_CONTROL = 0x45;
+ public static final byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46;
+ public static final byte RESOURCE_USAGE_ATTRIBUTE = 0x47;
+ public static final byte MEASUREMENT_UNITS = 0x4B;
+ public static final byte OBJECT_AREA_SIZE = 0x4C;
+ public static final byte AREA_DEFINITION = 0x4D;
+ public static final byte COLOR_SPECIFICATION = 0x4E;
+ public static final byte ENCODING_SCHEME_ID = 0x50;
+ public static final byte MEDIUM_MAP_PAGE_NUMBER = 0x56;
+ public static final byte OBJECT_BYTE_EXTENT = 0x57;
+ public static final byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58;
+ public static final byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59;
+ public static final byte OBJECT_OFFSET = 0x5A;
+ public static final byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D;
+ public static final byte OBJECT_COUNT = 0x5E;
+ public static final byte OBJECT_DATE_AND_TIMESTAMP = 0x62;
+ public static final byte COMMENT = 0x65;
+ public static final byte MEDIUM_ORIENTATION = 0x68;
+ public static final byte RESOURCE_OBJECT_INCLUDE = 0x6C;
+ public static final byte PRESENTATION_SPACE_RESET_MIXING = 0x70;
+ public static final byte PRESENTATION_SPACE_MIXING_RULE = 0x71;
+ public static final byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72;
+ public static final byte TONER_SAVER = 0x74;
+ public static final byte COLOR_FIDELITY = 0x75;
+ public static final byte FONT_FIDELITY = 0x78;
+ public static final byte ATTRIBUTE_QUALIFIER = (byte)0x80;
+ public static final byte PAGE_POSITION_INFORMATION = (byte)0x81;
+ public static final byte PARAMETER_VALUE = (byte)0x82;
+ public static final byte PRESENTATION_CONTROL = (byte)0x83;
+ public static final byte FONT_RESOLUTION_AND_METRIC_TECHNOLOGY = (byte)0x84;
+ public static final byte FINISHING_OPERATION = (byte)0x85;
+ public static final byte TEXT_FIDELITY = (byte)0x86;
+ public static final byte MEDIA_FIDELITY = (byte)0x87;
+ public static final byte FINISHING_FIDELITY = (byte)0x88;
+ public static final byte DATA_OBJECT_FONT_DESCRIPTOR = (byte)0x8B;
+ public static final byte LOCALE_SELECTOR = (byte)0x8C;
+ public static final byte UP3I_FINISHING_OPERATION = (byte)0x8E;
+ public static final byte COLOR_MANAGEMENT_RESOURCE_DESCRIPTOR = (byte)0x91;
+ public static final byte RENDERING_INTENT = (byte)0x95;
+ public static final byte CMR_TAG_FIDELITY = (byte)0x96;
+ public static final byte DEVICE_APPEARANCE = (byte)0x97;
+
+ /**
+ * the triplet identifier
+ */
+ protected byte id;
+
+ /**
+ * the triplet's data contents
+ */
+ protected byte[] data;
+
+ /**
+ * Main constructor
+ * @param id the triplet identifier (see static definitions above)
+ * @param contents the data item contained in this triplet
+ */
+ public Triplet(byte id, byte[] contents) {
+ this(id);
+ this.data = contents;
+ }
+
+ /**
+ * Constructor
+ * @param id the triplet identifier (see static definitions above)
+ */
+ public Triplet(byte id) {
+ this.id = id;
+ }
+
+ /**
+ * Constructor
+ * @param id the triplet identifier (see static definitions above)
+ * @param content the content byte data
+ */
+ public Triplet(byte id, byte content) {
+ this(id, new byte[] {content});
+ }
+
+ /**
+ * Constructor
+ * @param id the triplet identifier (see static definitions above)
+ * @param data the data item (in String form) contained in this triplet
+ * @throws UnsupportedEncodingException EBCIDIC encoding is not supported
+ */
+ public Triplet(byte id, String data) throws UnsupportedEncodingException {
+ this(id, data.getBytes(AFPConstants.EBCIDIC_ENCODING));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeDataStream(OutputStream os) throws IOException {
+ os.write((byte)data.length + 2);
+ os.write(id);
+ os.write(data);
+ }
+
+ /**
+ * @return the triplet identifier
+ */
+ public byte getId() {
+ return this.id;
+ }
+
+ /**
+ * @return the contents of the triplet
+ */
+ public byte[] getData() {
+ return this.data;
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 5b7dd840e..19f274902 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -1086,10 +1086,10 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
/**
* {@inheritDoc}
*/
- protected void fillRect(float x, float y, float w, float h) {
- if (w != 0 && h != 0) {
+ protected void fillRect(float x, float y, float width, float height) {
+ if (width > 0 && height > 0) {
currentStream.add(format(x) + " " + format(y) + " "
- + format(w) + " " + format(h) + " re f\n");
+ + format(width) + " " + format(height) + " re f\n");
}
}
@@ -1684,7 +1684,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
endTextObject();
putImage(url, pos, foreignAttributes);
}
-
+
/**
* Adds a PDF XObject (a bitmap or form) to the PDF that will later be referenced.
* @param uri URL of the bitmap
@@ -1767,6 +1767,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
this.pdfDoc.output(ostream);
} catch (IOException ioe) {
// ioexception will be caught later
+ log.error(ioe.getMessage());
}
}
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java
index 306cd7bda..4bbfa0c73 100644
--- a/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java
+++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentAfterElement.java
@@ -27,8 +27,6 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
*/
public class PSCommentAfterElement extends AbstractPSCommentElement {
- protected static final String ELEMENT = "ps-comment-after";
-
/**
* Main constructor
* @param parent node
@@ -42,7 +40,7 @@ public class PSCommentAfterElement extends AbstractPSCommentElement {
* @see org.apache.fop.fo.FONode#getLocalName()
*/
public String getLocalName() {
- return ELEMENT;
+ return PSCommentAfter.ELEMENT;
}
/**
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java
index 6058f355b..f05e7c7fe 100644
--- a/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java
+++ b/src/java/org/apache/fop/render/ps/extensions/PSCommentBeforeElement.java
@@ -27,8 +27,6 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
*/
public class PSCommentBeforeElement extends AbstractPSCommentElement {
- protected static final String ELEMENT = "ps-comment-before";
-
/**
* Main constructor
* @param parent parent node
@@ -42,7 +40,7 @@ public class PSCommentBeforeElement extends AbstractPSCommentElement {
* @see org.apache.fop.fo.FONode#getLocalName()
*/
public String getLocalName() {
- return ELEMENT;
+ return PSCommentBefore.ELEMENT;
}
/**
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
index 45ace5f80..b23ff54da 100644
--- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
+++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
@@ -42,8 +42,8 @@ public class PSExtensionElementMapping extends ElementMapping {
foObjs.put(PSSetupCodeElement.ELEMENT, new PSSetupCodeMaker());
foObjs.put(PSPageSetupCodeElement.ELEMENT, new PSPageSetupCodeMaker());
foObjs.put(PSSetPageDeviceElement.ELEMENT, new PSSetPageDeviceMaker());
- foObjs.put(PSCommentBeforeElement.ELEMENT, new PSCommentBeforeMaker());
- foObjs.put(PSCommentAfterElement.ELEMENT, new PSCommentAfterMaker());
+ foObjs.put(PSCommentBefore.ELEMENT, new PSCommentBeforeMaker());
+ foObjs.put(PSCommentAfter.ELEMENT, new PSCommentAfterMaker());
}
}