aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache')
-rw-r--r--src/java/org/apache/fop/afp/AFPGraphics2D.java193
-rw-r--r--src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java6
-rw-r--r--src/java/org/apache/fop/afp/AFPPaintingState.java13
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceManager.java5
-rw-r--r--src/java/org/apache/fop/afp/AFPStreamer.java7
-rw-r--r--src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java2
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java27
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPPageFonts.java (renamed from src/java/org/apache/fop/afp/AFPPageFonts.java)6
-rw-r--r--src/java/org/apache/fop/afp/fonts/package.html23
-rw-r--r--src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java1
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsFilletRelative.java42
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsLine.java3
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsLineRelative.java42
-rw-r--r--src/java/org/apache/fop/afp/goca/package.html23
-rw-r--r--src/java/org/apache/fop/afp/ioca/package.html23
-rw-r--r--src/java/org/apache/fop/afp/modca/GraphicsObject.java35
-rw-r--r--src/java/org/apache/fop/afp/modca/package.html23
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/package.html23
-rw-r--r--src/java/org/apache/fop/afp/package.html23
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPBridgeContext.java105
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPImageElementBridge.java37
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextElementBridge.java42
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextHandler.java (renamed from src/java/org/apache/fop/afp/AFPTextHandler.java)19
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextPainter.java (renamed from src/java/org/apache/fop/afp/AFPTextPainter.java)25
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java4
-rw-r--r--src/java/org/apache/fop/fonts/package.html17
-rw-r--r--src/java/org/apache/fop/pdf/package.html17
-rw-r--r--src/java/org/apache/fop/render/AbstractGenericSVGHandler.java42
-rw-r--r--src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java15
-rw-r--r--src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java211
-rw-r--r--src/java/org/apache/fop/render/ImageHandler.java46
-rw-r--r--src/java/org/apache/fop/render/PrintRenderer.java14
-rw-r--r--src/java/org/apache/fop/render/RendererContext.java36
-rw-r--r--src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java93
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java87
-rw-r--r--src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java (renamed from src/java/org/apache/fop/afp/AFPForeignAttributeReader.java)4
-rw-r--r--src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java103
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java135
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandler.java (renamed from src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java)45
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java128
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java (renamed from src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java)59
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java (renamed from src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java)56
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java42
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java (renamed from src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java)56
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java82
-rw-r--r--src/java/org/apache/fop/render/afp/AFPInfo.java30
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRenderer.java128
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java34
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererContext.java83
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java25
-rw-r--r--src/java/org/apache/fop/render/afp/AFPSVGHandler.java230
-rw-r--r--src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java89
-rw-r--r--src/java/org/apache/fop/render/afp/package.html23
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandler.java27
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java13
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java15
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java15
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java163
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java16
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java16
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java3
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java44
-rw-r--r--src/java/org/apache/fop/svg/AbstractFOPBridgeContext.java139
-rw-r--r--src/java/org/apache/fop/svg/AbstractFOPImageElementBridge.java284
-rw-r--r--src/java/org/apache/fop/svg/AbstractFOPTextElementBridge.java (renamed from src/java/org/apache/fop/afp/AFPTextElementBridge.java)39
-rw-r--r--src/java/org/apache/fop/svg/NativeImageHandler.java40
-rw-r--r--src/java/org/apache/fop/svg/PDFBridgeContext.java104
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java7
-rw-r--r--src/java/org/apache/fop/svg/PDFImageElementBridge.java233
-rw-r--r--src/java/org/apache/fop/svg/PDFTextElementBridge.java42
-rw-r--r--src/java/org/apache/fop/svg/PDFTextPainter.java7
71 files changed, 2328 insertions, 1561 deletions
diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java
index dd9a0dc03..df233dafa 100644
--- a/src/java/org/apache/fop/afp/AFPGraphics2D.java
+++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java
@@ -48,6 +48,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.svg.NativeImageHandler;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
@@ -65,7 +66,7 @@ import org.apache.xmlgraphics.util.MimeConstants;
*
* @see org.apache.xmlgraphics.java2d.AbstractGraphics2D
*/
-public class AFPGraphics2D extends AbstractGraphics2D {
+public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHandler {
private static final Log log = LogFactory.getLog(AFPGraphics2D.class);
@@ -109,10 +110,19 @@ public class AFPGraphics2D extends AbstractGraphics2D {
* @param textAsShapes
* if true, all text is turned into shapes in the convertion. No
* text is output.
- *
+ * @param paintingState painting state
+ * @param resourceManager resource manager
+ * @param resourceInfo resource info
+ * @param fontInfo font info
*/
- public AFPGraphics2D(boolean textAsShapes) {
+ public AFPGraphics2D(boolean textAsShapes, AFPPaintingState paintingState,
+ AFPResourceManager resourceManager, AFPResourceInfo resourceInfo,
+ FontInfo fontInfo) {
super(textAsShapes);
+ this.paintingState = paintingState;
+ this.resourceManager = resourceManager;
+ this.resourceInfo = resourceInfo;
+ this.fontInfo = fontInfo;
}
/**
@@ -123,12 +133,14 @@ public class AFPGraphics2D extends AbstractGraphics2D {
*/
public AFPGraphics2D(AFPGraphics2D g2d) {
super(g2d);
+ this.paintingState = g2d.paintingState;
+ this.resourceManager = g2d.resourceManager;
+ this.resourceInfo = g2d.resourceInfo;
+ this.fontInfo = g2d.fontInfo;
+
this.graphicsObj = g2d.graphicsObj;
this.fallbackTextHandler = g2d.fallbackTextHandler;
this.customTextHandler = g2d.customTextHandler;
- this.resourceManager = g2d.resourceManager;
- this.resourceInfo = g2d.resourceInfo;
- this.paintingState = g2d.paintingState;
}
/**
@@ -282,16 +294,13 @@ public class AFPGraphics2D extends AbstractGraphics2D {
mhr
);
} else {
- // graphics segment opening coordinates (x,y)
- // current position coordinates (x,y)
for (int[] openingCoords = new int[2], currCoords = new int[2];
!iter.isDone(); iter.next()) {
- // round the coordinate values and combine with current position
- // coordinates
int type = iter.currentSegment(dstPts);
if (type == PathIterator.SEG_MOVETO) {
openingCoords[X] = currCoords[X] = (int)Math.round(dstPts[X]);
openingCoords[Y] = currCoords[Y] = (int)Math.round(dstPts[Y]);
+ graphicsObj.setCurrentPosition(openingCoords);
} else {
int numCoords;
if (type == PathIterator.SEG_LINETO) {
@@ -303,32 +312,22 @@ public class AFPGraphics2D extends AbstractGraphics2D {
} else {
// close of the graphics segment
if (type == PathIterator.SEG_CLOSE) {
- coords = new int[] {
- coords[coords.length - 2], //prev X
- coords[coords.length - 1], //prev Y
- openingCoords[X],
- openingCoords[Y]
- };
- graphicsObj.addLine(coords);
+ graphicsObj.addLine(openingCoords, true);
} else {
log.debug("Unrecognised path iterator type: "
+ type);
}
continue;
}
- // combine current position coordinates with new graphics
- // segment coordinates
- coords = new int[numCoords + 2];
- coords[X] = currCoords[X];
- coords[Y] = currCoords[Y];
+ coords = new int[numCoords];
for (int i = 0; i < numCoords; i++) {
- coords[i + 2] = (int) Math.round(dstPts[i]);
+ coords[i] = (int) Math.round(dstPts[i]);
}
if (type == PathIterator.SEG_LINETO) {
- graphicsObj.addLine(coords);
+ graphicsObj.addLine(coords, true);
} else if (type == PathIterator.SEG_QUADTO
|| type == PathIterator.SEG_CUBICTO) {
- graphicsObj.addFillet(coords);
+ graphicsObj.addFillet(coords, true);
}
// update current position coordinates
currCoords[X] = coords[coords.length - 2];
@@ -408,7 +407,7 @@ public class AFPGraphics2D extends AbstractGraphics2D {
BufferedImage.TYPE_INT_ARGB);
}
- private AFPImageObjectInfo getImageObjectInfo(
+ private AFPImageObjectInfo createImageObjectInfo(
RenderedImage img, int x, int y, int width, int height) throws IOException {
ImageInfo imageInfo = new ImageInfo(null, "image/unknown");
ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
@@ -422,7 +421,8 @@ public class AFPGraphics2D extends AbstractGraphics2D {
imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
- imageObjectInfo.setBitsPerPixel(paintingState.getBitsPerPixel());
+ int bitsPerPixel = paintingState.getBitsPerPixel();
+ imageObjectInfo.setBitsPerPixel(bitsPerPixel);
imageObjectInfo.setResourceInfo(resourceInfo);
@@ -442,7 +442,6 @@ public class AFPGraphics2D extends AbstractGraphics2D {
// convert to grayscale
if (!colorImages) {
boas.reset();
- int bitsPerPixel = paintingState.getBitsPerPixel();
imageObjectInfo.setBitsPerPixel(bitsPerPixel);
ImageEncodingHelper.encodeRGBAsGrayScale(
imageData, dataWidth, dataHeight, bitsPerPixel, boas);
@@ -456,21 +455,10 @@ public class AFPGraphics2D extends AbstractGraphics2D {
// create object area info
AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
-
- AffineTransform at = gc.getTransform();
- float[] srcPts = new float[] {x, y};
- float[] dstPts = new float[srcPts.length];
- at.transform(srcPts, 0, dstPts, 0, 1);
- objectAreaInfo.setX(Math.round(dstPts[X]));
- objectAreaInfo.setY(Math.round(dstPts[Y]));
-
- AFPUnitConverter unitConv = paintingState.getUnitConverter();
-
- int w = Math.round(unitConv.pt2units(width));
- objectAreaInfo.setWidth(w);
-
- int h = Math.round(unitConv.pt2units(height));
- objectAreaInfo.setHeight(h);
+ objectAreaInfo.setX(x);
+ objectAreaInfo.setY(y);
+ objectAreaInfo.setWidth(width);
+ objectAreaInfo.setHeight(height);
int resolution = paintingState.getResolution();
objectAreaInfo.setWidthRes(resolution);
@@ -481,37 +469,62 @@ public class AFPGraphics2D extends AbstractGraphics2D {
return imageObjectInfo;
}
- /** {@inheritDoc} */
- public boolean drawImage(Image img, int x, int y, int width, int height,
- ImageObserver observer) {
-
- // draw with AWT Graphics2D
- Dimension size = new Dimension(width, height);
- BufferedImage bufferedImage = buildBufferedImage(size);
+ /**
+ * Draws an AWT image into a BufferedImage using an AWT Graphics2D implementation
+ *
+ * @param img the AWT image
+ * @param bufferedImage the AWT buffered image
+ * @param width the image width
+ * @param height the image height
+ * @param observer the image observer
+ * @return true if the image was drawn
+ */
+ private boolean drawBufferedImage(Image img, BufferedImage bufferedImage,
+ int width, int height, ImageObserver observer) {
java.awt.Graphics2D g2d = bufferedImage.createGraphics();
- g2d.setComposite(AlphaComposite.SrcOver);
+ try {
+ g2d.setComposite(AlphaComposite.SrcOver);
+
+ Color color = new Color(1, 1, 1, 0);
+ g2d.setBackground(color);
+ g2d.setPaint(color);
+
+ g2d.fillRect(0, 0, width, height);
- Color color = new Color(1, 1, 1, 0);
- g2d.setBackground(color);
- g2d.setPaint(color);
+ int imageWidth = bufferedImage.getWidth();
+ int imageHeight = bufferedImage.getHeight();
+ Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight);
+ g2d.clip(clipRect);
- g2d.fillRect(0, 0, width, height);
+ g2d.setComposite(gc.getComposite());
- int imageWidth = bufferedImage.getWidth();
- int imageHeight = bufferedImage.getHeight();
- Rectangle clipRect = new Rectangle(0, 0, imageWidth, imageHeight);
- g2d.clip(clipRect);
+ return g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
+ } finally {
+ g2d.dispose(); //drawn so dispose immediately to free system resource
+ }
+ }
- g2d.setComposite(gc.getComposite());
+ /** {@inheritDoc} */
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer) {
- boolean drawn = g2d.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
- g2d.dispose(); //drawn so dispose immediately to free system resource
+ // draw with AWT Graphics2D
+ Dimension imageSize = new Dimension(width, height);
+ BufferedImage bufferedImage = buildBufferedImage(imageSize);
+ boolean drawn = drawBufferedImage(img, bufferedImage, width, height, observer);
if (drawn) {
+ AffineTransform at = gc.getTransform();
+ float[] srcPts = new float[] {x, y};
+ float[] dstPts = new float[srcPts.length];
+ at.transform(srcPts, 0, dstPts, 0, 1);
+ x = Math.round(dstPts[X]);
+ y = Math.round(dstPts[Y]);
try {
// get image object info
- AFPImageObjectInfo imageObjectInfo = getImageObjectInfo(bufferedImage, x, y, width, height);
+ AFPImageObjectInfo imageObjectInfo
+ = createImageObjectInfo(bufferedImage, x, y, width, height);
// create image resource
resourceManager.createObject(imageObjectInfo);
@@ -524,24 +537,23 @@ public class AFPGraphics2D extends AbstractGraphics2D {
}
/** {@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 FontMetrics getFontMetrics(Font f) {
- log.debug("getFontMetrics() NYI: f=" + f);
- return null;
- }
+ int width = img.getWidth();
+ int height = img.getHeight();
- /** {@inheritDoc} */
- public void setXORMode(Color col) {
- log.debug("setXORMode() NYI: col=" + col);
+ AffineTransform at = paintingState.getData().getTransform();
+ AffineTransform gat = gc.getTransform();
+ int x = (int)Math.round(at.getTranslateX() + gat.getTranslateX());
+ int y = (int)Math.round(at.getTranslateY());
+ try {
+ // get image object info
+ AFPImageObjectInfo imageObjectInfo
+ = createImageObjectInfo(img, x, y, width, height);
+ // create image resource
+ resourceManager.createObject(imageObjectInfo);
+ } catch (IOException ioe) {
+ handleIOException(ioe);
+ }
}
/**
@@ -609,4 +621,27 @@ public class AFPGraphics2D extends AbstractGraphics2D {
public FontInfo getFontInfo() {
return this.fontInfo;
}
+
+ /** {@inheritDoc} */
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+ log.debug("drawRenderableImage() NYI: img=" + img + ", xform=" + xform);
+ }
+
+ /** {@inheritDoc} */
+ public FontMetrics getFontMetrics(Font f) {
+ log.debug("getFontMetrics() NYI: f=" + f);
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public void setXORMode(Color col) {
+ log.debug("setXORMode() NYI: col=" + col);
+ }
+
+ /** {@inheritDoc} */
+ public void addNativeImage(org.apache.xmlgraphics.image.loader.Image image,
+ float x, float y, float width, float height) {
+ log.debug("NYI: addNativeImage() "+ "image=" + image
+ + ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height);
+ }
}
diff --git a/src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java b/src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java
index df0ef55c5..cd8c7c303 100644
--- a/src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java
+++ b/src/java/org/apache/fop/afp/AFPGraphicsObjectInfo.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp;
+import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
@@ -62,7 +63,10 @@ public class AFPGraphicsObjectInfo extends AFPDataObjectInfo {
* @return the graphics area
*/
public Rectangle2D getArea() {
- return this.area;
+ AFPObjectAreaInfo objectAreaInfo = getObjectAreaInfo();
+ int width = objectAreaInfo.getWidth();
+ int height = objectAreaInfo.getHeight();
+ return new Rectangle(width, height);
}
/**
diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
index 60e4812b9..cb78fb36e 100644
--- a/src/java/org/apache/fop/afp/AFPPaintingState.java
+++ b/src/java/org/apache/fop/afp/AFPPaintingState.java
@@ -21,6 +21,7 @@ package org.apache.fop.afp;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.util.AbstractPaintingState;
/**
@@ -42,7 +43,7 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
private boolean colorImages = false;
/** images are supported in this AFP environment */
- private boolean nativeImages = false;
+ private boolean nativeImagesSupported = false;
/** default value for image depth */
private int bitsPerPixel = 8;
@@ -165,10 +166,10 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
/**
* Sets whether images are natively supported or not in the AFP environment
*
- * @param nativeImages true if images are natively supported in this AFP environment
+ * @param nativeImagesSupported true if images are natively supported in this AFP environment
*/
- public void setNativeImages(boolean nativeImages) {
- this.nativeImages = nativeImages;
+ public void setNativeImagesSupported(boolean nativeImagesSupported) {
+ this.nativeImagesSupported = nativeImagesSupported;
}
/**
@@ -176,8 +177,8 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
*
* @return true if images are supported natively in this AFP environment
*/
- public boolean isNativeImages() {
- return this.nativeImages;
+ public boolean isNativeImagesSupported() {
+ return this.nativeImagesSupported;
}
/**
diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java
index c912b8b17..21de78250 100644
--- a/src/java/org/apache/fop/afp/AFPResourceManager.java
+++ b/src/java/org/apache/fop/afp/AFPResourceManager.java
@@ -23,8 +23,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.modca.AbstractDataObject;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.afp.modca.DataStream;
@@ -36,9 +34,6 @@ import org.apache.fop.afp.modca.ResourceGroup;
* Manages the creation and storage of document resources
*/
public class AFPResourceManager {
- /** Static logging instance */
- private static final Log log = LogFactory.getLog(AFPResourceManager.class);
-
/** The AFP datastream (document tree) */
private DataStream dataStream;
diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java
index 1d9367ef6..269e6ae08 100644
--- a/src/java/org/apache/fop/afp/AFPStreamer.java
+++ b/src/java/org/apache/fop/afp/AFPStreamer.java
@@ -44,7 +44,7 @@ public class AFPStreamer implements Streamable {
private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_";
- private static final int BUFFER_SIZE = 4096;
+ private static final int BUFFER_SIZE = 4096; // 4k writing buffer
private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";
@@ -159,8 +159,8 @@ public class AFPStreamer implements Streamable {
*
* @throws IOException if an an I/O exception of some sort has occurred
*/
- public void close() throws IOException {
// write out any external resource groups
+ public void close() throws IOException {
Iterator it = pathResourceGroupMap.entrySet().iterator();
while (it.hasNext()) {
StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next();
@@ -192,6 +192,7 @@ public class AFPStreamer implements Streamable {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
+// long start = System.currentTimeMillis();
int len = (int)documentFile.length();
int numChunks = len / BUFFER_SIZE;
int remainingChunkSize = len % BUFFER_SIZE;
@@ -212,5 +213,7 @@ public class AFPStreamer implements Streamable {
os.write(buffer, 0, remainingChunkSize);
}
os.flush();
+// long end = System.currentTimeMillis();
+// log.debug("writing time " + (end - start) + "ms");
}
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java b/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java
index 1a2883e72..6a7538550 100644
--- a/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java
+++ b/src/java/org/apache/fop/afp/Graphics2DImagePainterGOCA.java
@@ -51,7 +51,7 @@ public class Graphics2DImagePainterGOCA extends Graphics2DImagePainterImpl {
/** {@inheritdoc} */
public void prepare(Graphics2D g2d, Rectangle2D area) {
double tx = area.getX();
- double ty = area.getHeight() - area.getY();
+ double ty = area.getHeight() + area.getY();
if (tx != 0 || ty != 0) {
g2d.translate(tx, ty);
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java b/src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java
index 1dd22c66a..de7f7f5be 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPFontAttributes.java
@@ -23,32 +23,24 @@ package org.apache.fop.afp.fonts;
* This class encapsulates the font attributes that need to be included
* in the AFP data stream. This class does not assist in converting the
* font attributes to AFP code pages and character set values.
- *
*/
public class AFPFontAttributes {
- /**
- * The font reference
- */
+ /** the font reference */
private int fontReference;
- /**
- * The font key
- */
+ /** the font key */
private final String fontKey;
- /**
- * The font
- */
+ /** the font */
private final AFPFont font;
- /**
- * The point size
- */
+ /** the point size */
private final int pointSize;
/**
* Constructor for the AFPFontAttributes
+ *
* @param fontKey the font key
* @param font the font
* @param pointSize the point size
@@ -60,6 +52,8 @@ public class AFPFontAttributes {
}
/**
+ * Return the font
+ *
* @return the font
*/
public AFPFont getFont() {
@@ -67,6 +61,8 @@ public class AFPFontAttributes {
}
/**
+ * Return the FontKey attribute
+ *
* @return the FontKey attribute
*/
public String getFontKey() {
@@ -74,6 +70,8 @@ public class AFPFontAttributes {
}
/**
+ * Return the point size attribute
+ *
* @return the point size attribute
*/
public int getPointSize() {
@@ -81,6 +79,8 @@ public class AFPFontAttributes {
}
/**
+ * Return the FontReference attribute
+ *
* @return the FontReference attribute
*/
public int getFontReference() {
@@ -89,6 +89,7 @@ public class AFPFontAttributes {
/**
* Sets the FontReference attribute
+ *
* @param fontReference the FontReference to set
*/
public void setFontReference(int fontReference) {
diff --git a/src/java/org/apache/fop/afp/AFPPageFonts.java b/src/java/org/apache/fop/afp/fonts/AFPPageFonts.java
index 41fce731d..146c6f14b 100644
--- a/src/java/org/apache/fop/afp/AFPPageFonts.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPPageFonts.java
@@ -17,11 +17,7 @@
/* $Id$ */
-package org.apache.fop.afp;
-
-import org.apache.fop.afp.fonts.AFPFont;
-import org.apache.fop.afp.fonts.AFPFontAttributes;
-
+package org.apache.fop.afp.fonts;
/**
* Holds the current page fonts
diff --git a/src/java/org/apache/fop/afp/fonts/package.html b/src/java/org/apache/fop/afp/fonts/package.html
new file mode 100644
index 000000000..74f8bf450
--- /dev/null
+++ b/src/java/org/apache/fop/afp/fonts/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.goca Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP Graphics Object Content Architecture (GOCA) structured objects.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java b/src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java
index 6f993b840..3adcd9466 100644
--- a/src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java
+++ b/src/java/org/apache/fop/afp/goca/AbstractGraphicsCoord.java
@@ -73,7 +73,6 @@ public abstract class AbstractGraphicsCoord extends AbstractPreparedAFPObject {
* Returns the length of this order code (typically this is the same as the coordinate length)
*
* @return the length of this order code
- *
*/
protected int getLength() {
return this.coords.length * 2;
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsFilletRelative.java b/src/java/org/apache/fop/afp/goca/GraphicsFilletRelative.java
new file mode 100644
index 000000000..b0e408405
--- /dev/null
+++ b/src/java/org/apache/fop/afp/goca/GraphicsFilletRelative.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.goca;
+
+/**
+ * A GOCA graphics curved tangential line to a specified set of
+ * straight lines drawn from the given position or current position
+ */
+public final class GraphicsFilletRelative extends AbstractGraphicsCoord {
+
+ /**
+ * Constructor
+ *
+ * @param coords the x/y coordinates for this object
+ */
+ public GraphicsFilletRelative(int[] coords) {
+ super(coords);
+ }
+
+ /** {@inheritDoc} */
+ protected byte getOrderCode() {
+ return (byte)0x85;
+ }
+
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsLine.java b/src/java/org/apache/fop/afp/goca/GraphicsLine.java
index 319a9a122..99f54b2d1 100644
--- a/src/java/org/apache/fop/afp/goca/GraphicsLine.java
+++ b/src/java/org/apache/fop/afp/goca/GraphicsLine.java
@@ -19,10 +19,9 @@
package org.apache.fop.afp.goca;
-
/**
* A GOCA graphics straight line drawn from the
- * given position or current position.
+ * given position
*/
public class GraphicsLine extends AbstractGraphicsCoord {
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsLineRelative.java b/src/java/org/apache/fop/afp/goca/GraphicsLineRelative.java
new file mode 100644
index 000000000..1eddc5129
--- /dev/null
+++ b/src/java/org/apache/fop/afp/goca/GraphicsLineRelative.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.goca;
+
+/**
+ * A GOCA graphics straight line drawn from the
+ * relative from the current position.
+ */
+public class GraphicsLineRelative extends AbstractGraphicsCoord {
+
+ /**
+ * Constructor
+ *
+ * @param coords the x/y coordinates for this object
+ */
+ public GraphicsLineRelative(int[] coords) {
+ super(coords);
+ }
+
+ /** {@inheritDoc} */
+ protected byte getOrderCode() {
+ return (byte)0x81;
+ }
+
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/goca/package.html b/src/java/org/apache/fop/afp/goca/package.html
new file mode 100644
index 000000000..539be8d13
--- /dev/null
+++ b/src/java/org/apache/fop/afp/goca/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.fonts Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP font related classes.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/ioca/package.html b/src/java/org/apache/fop/afp/ioca/package.html
new file mode 100644
index 000000000..34e0bc19d
--- /dev/null
+++ b/src/java/org/apache/fop/afp/ioca/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.ioca Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP Image Object Content Architecture (IOCA) structured objects.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/afp/modca/GraphicsObject.java
index 8b76dde15..3848ca4c3 100644
--- a/src/java/org/apache/fop/afp/modca/GraphicsObject.java
+++ b/src/java/org/apache/fop/afp/modca/GraphicsObject.java
@@ -30,8 +30,10 @@ import org.apache.fop.afp.Factory;
import org.apache.fop.afp.goca.GraphicsBox;
import org.apache.fop.afp.goca.GraphicsData;
import org.apache.fop.afp.goca.GraphicsFillet;
+import org.apache.fop.afp.goca.GraphicsFilletRelative;
import org.apache.fop.afp.goca.GraphicsFullArc;
import org.apache.fop.afp.goca.GraphicsLine;
+import org.apache.fop.afp.goca.GraphicsLineRelative;
import org.apache.fop.afp.goca.GraphicsSetArcParameters;
import org.apache.fop.afp.goca.GraphicsSetCharacterSet;
import org.apache.fop.afp.goca.GraphicsSetCurrentPosition;
@@ -181,7 +183,21 @@ public class GraphicsObject extends AbstractDataObject {
* @param coords the x/y coordinates (can be a series)
*/
public void addLine(int[] coords) {
- addObject(new GraphicsLine(coords));
+ addLine(coords, false);
+ }
+
+ /**
+ * Adds a line at the given x/y coordinates
+ *
+ * @param coords the x/y coordinates (can be a series)
+ * @param relative relative true for a line at current position (relative to)
+ */
+ public void addLine(int[] coords, boolean relative) {
+ if (relative) {
+ addObject(new GraphicsLineRelative(coords));
+ } else {
+ addObject(new GraphicsLine(coords));
+ }
}
/**
@@ -199,7 +215,21 @@ public class GraphicsObject extends AbstractDataObject {
* @param coords the x/y coordinates
*/
public void addFillet(int[] coords) {
- addObject(new GraphicsFillet(coords));
+ addFillet(coords, false);
+ }
+
+ /**
+ * Adds a fillet (curve) at the given coordinates
+ *
+ * @param coords the x/y coordinates
+ * @param relative relative true for a fillet at current position (relative to)
+ */
+ public void addFillet(int[] coords, boolean relative) {
+ if (relative) {
+ addObject(new GraphicsFilletRelative(coords));
+ } else {
+ addObject(new GraphicsFillet(coords));
+ }
}
/**
@@ -300,4 +330,5 @@ public class GraphicsObject extends AbstractDataObject {
copySF(data, Type.END, Category.GRAPHICS);
os.write(data);
}
+
} \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/modca/package.html b/src/java/org/apache/fop/afp/modca/package.html
new file mode 100644
index 000000000..572743558
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.modca Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP Mixed Object Document Content Architecture (MO:DCA) structured objects.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/modca/triplets/package.html b/src/java/org/apache/fop/afp/modca/triplets/package.html
new file mode 100644
index 000000000..99ae55a45
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/triplets/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp.modca.triplets Package</TITLE>
+<BODY>
+<P>Contains a collection of AFP Mixed Object Document Content Architecture (MO:DCA) triplet classes.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/package.html b/src/java/org/apache/fop/afp/package.html
new file mode 100644
index 000000000..d67498159
--- /dev/null
+++ b/src/java/org/apache/fop/afp/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.afp Package</TITLE>
+<BODY>
+<P>Contains an AFP library.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
new file mode 100644
index 000000000..5434b5b9d
--- /dev/null
+++ b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.svg;
+
+import java.awt.geom.AffineTransform;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.UserAgent;
+import org.apache.batik.gvt.TextPainter;
+import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.svg.AbstractFOPBridgeContext;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+
+public class AFPBridgeContext extends AbstractFOPBridgeContext {
+
+ private final AFPGraphics2D g2d;
+
+ /**
+ * Constructs a new bridge context.
+ *
+ * @param userAgent the user agent
+ * @param fontInfo the font list for the text painter, may be null
+ * in which case text is painted as shapes
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ * @param g2d an AFPGraphics 2D implementation
+ */
+ public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo,
+ ImageManager imageManager, ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform, AFPGraphics2D g2d) {
+ super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
+ this.g2d = g2d;
+ }
+
+ /**
+ * Constructs a new bridge context.
+ * @param userAgent the user agent
+ * @param loader the Document Loader to use for referenced documents.
+ * @param fontInfo the font list for the text painter, may be null
+ * in which case text is painted as shapes
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ * @param an AFPGraphics 2D implementation
+ */
+ public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
+ FontInfo fontInfo, ImageManager imageManager,
+ ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform, AFPGraphics2D g2d) {
+ super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
+ this.g2d = g2d;
+ }
+
+ /** {@inheritDoc} */
+ public void registerSVGBridges() {
+ super.registerSVGBridges();
+
+ if (fontInfo != null) {
+ AFPTextHandler textHandler = new AFPTextHandler(g2d);
+ g2d.setCustomTextHandler(textHandler);
+
+ TextPainter textPainter = new AFPTextPainter(textHandler);
+ setTextPainter(textPainter);
+
+ putBridge(new AFPTextElementBridge(textPainter));
+ }
+
+ putBridge(new AFPImageElementBridge());
+ }
+
+ /** {@inheritDoc} */
+ public BridgeContext createBridgeContext() {
+ return new AFPBridgeContext(getUserAgent(), getDocumentLoader(),
+ fontInfo,
+ getImageManager(),
+ getImageSessionContext(),
+ linkTransform, g2d);
+ }
+
+}
diff --git a/src/java/org/apache/fop/afp/svg/AFPImageElementBridge.java b/src/java/org/apache/fop/afp/svg/AFPImageElementBridge.java
new file mode 100644
index 000000000..de677e7ab
--- /dev/null
+++ b/src/java/org/apache/fop/afp/svg/AFPImageElementBridge.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.svg;
+
+import org.apache.fop.svg.AbstractFOPImageElementBridge;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+
+public class AFPImageElementBridge extends AbstractFOPImageElementBridge {
+
+ private final ImageFlavor[] supportedFlavors = new ImageFlavor[]
+ {ImageFlavor.RAW_JPEG,
+ ImageFlavor.RAW_CCITTFAX,
+ ImageFlavor.GRAPHICS2D,
+ ImageFlavor.XML_DOM};
+
+ /** {@inheritDoc} */
+ protected ImageFlavor[] getSupportedFlavours() {
+ return supportedFlavors;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/svg/AFPTextElementBridge.java b/src/java/org/apache/fop/afp/svg/AFPTextElementBridge.java
new file mode 100644
index 000000000..31aa3fe60
--- /dev/null
+++ b/src/java/org/apache/fop/afp/svg/AFPTextElementBridge.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.svg;
+
+import org.apache.batik.gvt.TextPainter;
+import org.apache.fop.svg.AbstractFOPTextElementBridge;
+
+/**
+ * Bridge class for the &lt;text> element.
+ * This bridge will use the direct text painter if the text
+ * for the element is simple.
+ */
+public class AFPTextElementBridge extends AbstractFOPTextElementBridge {
+
+ /**
+ * Constructs a new bridge for the &lt;text> element.
+ *
+ * @param textPainter the text painter to use
+ */
+ public AFPTextElementBridge(TextPainter textPainter) {
+ super(textPainter);
+ }
+
+}
+
diff --git a/src/java/org/apache/fop/afp/AFPTextHandler.java b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
index 77dc641b9..d78e5c16e 100644
--- a/src/java/org/apache/fop/afp/AFPTextHandler.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
@@ -17,16 +17,18 @@
/* $Id$ */
-package org.apache.fop.afp;
+package org.apache.fop.afp.svg;
import java.awt.Color;
-import java.awt.geom.AffineTransform;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontAttributes;
+import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.afp.modca.GraphicsObject;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -41,9 +43,6 @@ public class AFPTextHandler implements TextHandler {
/** logging instance */
private static Log log = LogFactory.getLog(AFPTextHandler.class);
- private static final int X = 0;
- private static final int Y = 1;
-
private AFPGraphics2D g2d = null;
/** Overriding FontState */
@@ -113,7 +112,7 @@ public class AFPTextHandler implements TextHandler {
fontReference = registerPageFont(internalFontName, fontSize);
} else {
java.awt.Font awtFont = g2d.getFont();
- AffineTransform fontTransform = awtFont.getTransform();
+// AffineTransform fontTransform = awtFont.getTransform();
FontInfo fontInfo = getFontInfo();
Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
String internalFontName = fopFont.getFontName();
@@ -122,14 +121,8 @@ public class AFPTextHandler implements TextHandler {
}
graphicsObj.setCharacterSet(fontReference);
- // calculate x, y plotting coordinates from graphics context
- AffineTransform at = g2d.getTransform();
- float[] srcPts = new float[] { x, y };
- float[] dstPts = new float[srcPts.length];
- at.transform(srcPts, 0, dstPts, 0, 1);
-
// add the character string
- graphicsObj.addString(str, Math.round(dstPts[X]), Math.round(dstPts[Y]));
+ graphicsObj.addString(str, Math.round(x), Math.round(y));
}
/**
diff --git a/src/java/org/apache/fop/afp/AFPTextPainter.java b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
index 7e3f3405f..2d68616a3 100644
--- a/src/java/org/apache/fop/afp/AFPTextPainter.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
@@ -17,13 +17,14 @@
/* $Id$ */
-package org.apache.fop.afp;
+package org.apache.fop.afp.svg;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.font.TextAttribute;
+import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
@@ -42,6 +43,7 @@ import org.apache.batik.gvt.text.Mark;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
@@ -80,6 +82,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Paints the specified attributed character iterator using the
* specified Graphics2D and context and font context.
+ *
* @param node the TextNode to paint
* @param g2d the Graphics2D to use
*/
@@ -87,10 +90,10 @@ public class AFPTextPainter implements TextPainter {
Point2D loc = node.getLocation();
log.debug("painting text node " + node);
if (hasUnsupportedAttributes(node)) {
- log.debug("hasunsuportedattributes");
+ log.debug("hasUnsuportedAttributes");
PROXY_PAINTER.paint(node, g2d);
} else {
- log.debug("allattributessupported");
+ log.debug("allAttributesSupported");
paintTextRuns(node.getTextRuns(), g2d, loc);
}
}
@@ -221,7 +224,8 @@ public class AFPTextPainter implements TextPainter {
aci.first();
updateLocationFromACI(aci, loc);
- loc = g2d.getTransform().transform(loc, null);
+ AffineTransform at = g2d.getTransform();
+ loc = at.transform(loc, null);
// font
Font font = makeFont(aci);
@@ -240,6 +244,7 @@ public class AFPTextPainter implements TextPainter {
}
g2d.setPaint(foreground);
+ // text
String txt = getText(aci);
float advance = getStringWidth(txt, font);
float tx = 0;
@@ -258,9 +263,11 @@ public class AFPTextPainter implements TextPainter {
}
// draw string
+ double x = loc.getX();
+ double y = loc.getY();
try {
try {
- nativeTextHandler.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY()));
+ nativeTextHandler.drawString(txt, (float)x + tx, (float)y);
} catch (IOException ioe) {
if (g2d instanceof AFPGraphics2D) {
((AFPGraphics2D)g2d).handleIOException(ioe);
@@ -424,6 +431,7 @@ public class AFPTextPainter implements TextPainter {
* Get the geometry bounds.
* This uses the StrokingTextPainter to get the bounds
* since in theory it should be the same.
+ *
* @param node the text node
* @return the bounds of the text
*/
@@ -436,6 +444,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Get the mark.
* This does nothing since the output is AFP and not interactive.
+ *
* @param node the text node
* @param pos the position
* @param all select all
@@ -448,6 +457,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Select at.
* This does nothing since the output is AFP and not interactive.
+ *
* @param x the x position
* @param y the y position
* @param node the text node
@@ -460,6 +470,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Select to.
* This does nothing since the output is AFP and not interactive.
+ *
* @param x the x position
* @param y the y position
* @param beginMark the start mark
@@ -472,6 +483,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Selec first.
* This does nothing since the output is AFP and not interactive.
+ *
* @param node the text node
* @return null
*/
@@ -482,6 +494,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Select last.
* This does nothing since the output is AFP and not interactive.
+ *
* @param node the text node
* @return null
*/
@@ -492,6 +505,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Get selected.
* This does nothing since the output is AFP and not interactive.
+ *
* @param start the start mark
* @param finish the finish mark
* @return null
@@ -503,6 +517,7 @@ public class AFPTextPainter implements TextPainter {
/**
* Get the highlighted shape.
* This does nothing since the output is AFP and not interactive.
+ *
* @param beginMark the start mark
* @param endMark the end mark
* @return null
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
index 1a04d129a..8f8032767 100644
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ b/src/java/org/apache/fop/fonts/FontInfo.java
@@ -389,8 +389,8 @@ public class FontInfo {
}
matchedTriplet = fontLookup(awtFontFamily, awtFontStyle, awtFontWeight);
}
- float awtFontSize = awtFont.getSize2D();
- return getFontInstance(matchedTriplet, (int)(awtFontSize * 1000 + 0.5));
+ int fontSize = Math.round(awtFont.getSize2D() * 1000);
+ return getFontInstance(matchedTriplet, fontSize);
}
/**
diff --git a/src/java/org/apache/fop/fonts/package.html b/src/java/org/apache/fop/fonts/package.html
index 33e1e2cb3..fee0bf827 100644
--- a/src/java/org/apache/fop/fonts/package.html
+++ b/src/java/org/apache/fop/fonts/package.html
@@ -1,3 +1,20 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
<HTML>
<TITLE>org.apache.fop.fonts Package</TITLE>
<BODY>
diff --git a/src/java/org/apache/fop/pdf/package.html b/src/java/org/apache/fop/pdf/package.html
index e86318adc..383f78da1 100644
--- a/src/java/org/apache/fop/pdf/package.html
+++ b/src/java/org/apache/fop/pdf/package.html
@@ -1,3 +1,20 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
<HTML>
<TITLE>org.apache.fop.pdf Package</TITLE>
<BODY>
diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
index 18cc81400..5c253fe94 100644
--- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
+++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
@@ -29,10 +29,12 @@ 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.fop.apps.FOUserAgent;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.image.loader.batik.Graphics2DImagePainterImpl;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
+import org.apache.fop.render.afp.AFPGraphics2DAdapter;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
@@ -71,7 +73,7 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
* @param imageSize the image size
* @return a new graphics 2D image painter implementation
*/
- protected Graphics2DImagePainter createPainter(
+ protected Graphics2DImagePainter createGraphics2DImagePainter(
GraphicsNode root, BridgeContext ctx, Dimension imageSize) {
return new Graphics2DImagePainterImpl(root, ctx, imageSize);
}
@@ -85,14 +87,14 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
* @return a built GVT root tree
*/
protected GraphicsNode buildGraphicsNode(
- RendererContext rendererContext, BridgeContext ctx, Document doc) {
+ FOUserAgent userAgent, BridgeContext ctx, Document doc) {
GVTBuilder builder = new GVTBuilder();
final GraphicsNode root;
try {
root = builder.build(ctx, doc);
} catch (Exception e) {
EventBroadcaster eventBroadcaster
- = rendererContext.getUserAgent().getEventBroadcaster();
+ = userAgent.getEventBroadcaster();
SVGEventProducer eventProducer = SVGEventProducer.Provider.get(eventBroadcaster);
final String uri = getDocumentURI(doc);
eventProducer.svgNotBuilt(this, e, uri);
@@ -102,6 +104,18 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
}
/**
+ * Returns the image size
+ * @param wrappedContext renderer context wrapper
+ *
+ * @return the image size
+ */
+ protected Dimension getImageSize(RendererContextWrapper wrappedContext) {
+ final int width = wrappedContext.getWidth();
+ final int height = wrappedContext.getHeight();
+ return new Dimension(width, height);
+ }
+
+ /**
* Render the SVG document.
*
* @param rendererContext the renderer context
@@ -113,23 +127,21 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
updateRendererContext(rendererContext);
//Prepare
- SVGUserAgent svgUserAgent = new SVGUserAgent(
- rendererContext.getUserAgent(), new AffineTransform());
+ FOUserAgent userAgent = rendererContext.getUserAgent();
+ SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform());
+
+ //Create Batik BridgeContext
final BridgeContext bridgeContext = new BridgeContext(svgUserAgent);
//Build the GVT tree
- final GraphicsNode root = buildGraphicsNode(rendererContext, bridgeContext, doc);
+ final GraphicsNode root = buildGraphicsNode(userAgent, bridgeContext, doc);
+
+ // Create Graphics2DImagePainter
final RendererContextWrapper wrappedContext = RendererContext.wrapRendererContext(
rendererContext);
-
- //Get Image Size
- final int width = wrappedContext.getWidth();
- final int height = wrappedContext.getHeight();
- Dimension imageSize = new Dimension(width, height);
-
- //Create the painter
- final Graphics2DImagePainter painter = createPainter(root, bridgeContext, imageSize);
+ Dimension imageSize = getImageSize(wrappedContext);
+ final Graphics2DImagePainter painter = createGraphics2DImagePainter(root, bridgeContext, imageSize);
//Let the painter paint the SVG on the Graphics2D instance
Graphics2DAdapter g2dAdapter = rendererContext.getRenderer().getGraphics2DAdapter();
@@ -137,6 +149,8 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
//Paint the image
final int x = wrappedContext.getCurrentXPosition();
final int y = wrappedContext.getCurrentYPosition();
+ final int width = wrappedContext.getWidth();
+ final int height = wrappedContext.getHeight();
g2dAdapter.paintImage(painter, rendererContext, x, y, width, height);
}
diff --git a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java
index 5861fb042..ee18dff0d 100644
--- a/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java
+++ b/src/java/org/apache/fop/render/AbstractGraphics2DAdapter.java
@@ -54,8 +54,8 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter {
protected BufferedImage paintToBufferedImage(
org.apache.xmlgraphics.java2d.Graphics2DImagePainter painter,
RendererContextWrapper context, int resolution, boolean gray, boolean withAlpha) {
- int bmw = (int)Math.ceil(UnitConv.mpt2px(context.getWidth(), resolution));
- int bmh = (int)Math.ceil(UnitConv.mpt2px(context.getHeight(), resolution));
+ int bmw = mpt2px(context.getWidth(), resolution);
+ int bmh = mpt2px(context.getHeight(), resolution);
BufferedImage bi;
if (gray) {
if (withAlpha) {
@@ -102,6 +102,17 @@ public abstract class AbstractGraphics2DAdapter implements Graphics2DAdapter {
return bi;
}
+ /**
+ * Converts millipoints to pixels
+ *
+ * @param unit the unit to convert in mpts
+ * @param resolution the target resolution
+ * @return the converted unit in pixels
+ */
+ protected int mpt2px(int unit, int resolution) {
+ return (int)Math.ceil(UnitConv.mpt2px(unit, resolution));
+ }
+
private static BufferedImage createGrayBufferedImageWithAlpha(int width, int height) {
BufferedImage bi;
boolean alphaPremultiplied = true;
diff --git a/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java b/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java
new file mode 100644
index 000000000..e305e0a55
--- /dev/null
+++ b/src/java/org/apache/fop/render/AbstractImageHandlerRegistry.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.util.Service;
+
+/**
+ * This class holds references to various image handlers used by the renderers. It also
+ * supports automatic discovery of additional handlers available through
+ * the class path.
+ */
+public abstract class AbstractImageHandlerRegistry {
+
+ /** the logger */
+ private static Log log = LogFactory.getLog(AbstractImageHandlerRegistry.class);
+
+ private static final Comparator HANDLER_COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2) {
+ ImageHandler h1 = (ImageHandler)o1;
+ ImageHandler h2 = (ImageHandler)o2;
+ return h1.getPriority() - h2.getPriority();
+ }
+ };
+
+ /** Map containing image handlers for various MIME types */
+ private final Map/*<Class, ImageHandler>*/ handlers
+ = new java.util.HashMap/*<Class, ImageHandler>*/();
+
+ /** List containing the same handlers as above but ordered by priority */
+ private final List/*<ImageHandler>*/ handlerList
+ = new java.util.LinkedList/*<ImageHandler>*/();
+
+ /** Sorted Set of registered handlers */
+ private ImageFlavor[] supportedFlavors = new ImageFlavor[0];
+
+ private int handlerRegistrations;
+ private int lastSync;
+
+ /**
+ * Default constructor.
+ */
+ public AbstractImageHandlerRegistry() {
+ discoverHandlers();
+ }
+
+ /**
+ * Add an ImageHandler. The handler itself is inspected to find out what it supports.
+ * @param classname the fully qualified class name
+ */
+ public void addHandler(String classname) {
+ try {
+ ImageHandler handlerInstance
+ = (ImageHandler)Class.forName(classname).newInstance();
+ addHandler(handlerInstance);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("Could not find "
+ + classname);
+ } catch (InstantiationException e) {
+ throw new IllegalArgumentException("Could not instantiate "
+ + classname);
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException("Could not access "
+ + classname);
+ } catch (ClassCastException e) {
+ throw new IllegalArgumentException(classname
+ + " is not an "
+ + getHandlerClass().getName());
+ }
+ }
+
+ /**
+ * Add an image handler. The handler itself is inspected to find out what it supports.
+ * @param handler the ImageHandler instance
+ */
+ public synchronized void addHandler(ImageHandler handler) {
+ Class[] imageClasses = handler.getSupportedImageClasses();
+ for (int i = 0; i < imageClasses.length; i++) {
+ this.handlers.put(imageClasses[i], handler);
+ }
+
+ //Sorted insert
+ ListIterator iter = this.handlerList.listIterator();
+ while (iter.hasNext()) {
+ ImageHandler h = (ImageHandler)iter.next();
+ if (getHandlerComparator().compare(handler, h) < 0) {
+ iter.previous();
+ break;
+ }
+ }
+ iter.add(handler);
+ this.handlerRegistrations++;
+ }
+
+ /**
+ * Returns an ImageHandler which handles an specific image type given the MIME type
+ * of the image.
+ * @param img the Image to be handled
+ * @return the ImageHandler responsible for handling the image or null if none is available
+ */
+ public ImageHandler getHandler(Image img) {
+ return getHandler(img.getClass());
+ }
+
+ /**
+ * Returns an ImageHandler which handles an specific image type given the MIME type
+ * of the image.
+ * @param imageClass the Image subclass for which to get a handler
+ * @return the ImageHandler responsible for handling the image or null if none is available
+ */
+ public synchronized ImageHandler getHandler(Class imageClass) {
+ ImageHandler handler = null;
+ Class cl = imageClass;
+ while (cl != null) {
+ handler = (ImageHandler)handlers.get(cl);
+ if (handler != null) {
+ break;
+ }
+ cl = cl.getSuperclass();
+ }
+ return handler;
+ }
+
+ /**
+ * Returns the ordered array of supported image flavors.
+ * @return the array of image flavors
+ */
+ public synchronized ImageFlavor[] getSupportedFlavors() {
+ if (this.lastSync != this.handlerRegistrations) {
+ //Extract all ImageFlavors into a single array
+ List flavors = new java.util.ArrayList();
+ Iterator iter = this.handlerList.iterator();
+ while (iter.hasNext()) {
+ ImageFlavor[] f = ((ImageHandler)iter.next()).getSupportedImageFlavors();
+ for (int i = 0; i < f.length; i++) {
+ flavors.add(f[i]);
+ }
+ }
+ this.supportedFlavors = (ImageFlavor[])flavors.toArray(new ImageFlavor[flavors.size()]);
+ this.lastSync = this.handlerRegistrations;
+ }
+ return this.supportedFlavors;
+ }
+
+ /**
+ * Discovers ImageHandler implementations through the classpath and dynamically
+ * registers them.
+ */
+ private void discoverHandlers() {
+ // add mappings from available services
+ Class imageHandlerClass = getHandlerClass();
+ Iterator providers = Service.providers(imageHandlerClass);
+ if (providers != null) {
+ while (providers.hasNext()) {
+ ImageHandler handler = (ImageHandler)providers.next();
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Dynamically adding ImageHandler: "
+ + handler.getClass().getName());
+ }
+ addHandler(handler);
+ } catch (IllegalArgumentException e) {
+ log.error("Error while adding ImageHandler", e);
+ }
+
+ }
+ }
+ }
+
+ /**
+ * Returns the ImageHandler comparator
+ *
+ * @return the ImageHandler comparator
+ */
+ public Comparator getHandlerComparator() {
+ return HANDLER_COMPARATOR;
+ }
+
+ /**
+ * Returns the ImageHandler implementing class
+ *
+ * @return the ImageHandler implementing class
+ */
+ public abstract Class getHandlerClass();
+}
diff --git a/src/java/org/apache/fop/render/ImageHandler.java b/src/java/org/apache/fop/render/ImageHandler.java
new file mode 100644
index 000000000..05d1e2e79
--- /dev/null
+++ b/src/java/org/apache/fop/render/ImageHandler.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+
+public interface ImageHandler {
+
+ /**
+ * Returns the priority for this image handler. A lower value means higher priority. This
+ * information is used to build the ordered/prioritized list of supported ImageFlavors for
+ * the PDF renderer. The built-in handlers use priorities between 100 and 999.
+ * @return a positive integer (>0) indicating the priority
+ */
+ int getPriority();
+
+ /**
+ * Returns the {@link ImageFlavor}s supported by this instance
+ * @return the supported image flavors
+ */
+ ImageFlavor[] getSupportedImageFlavors();
+
+ /**
+ * Returns the {@link Image} subclasses supported by this instance.
+ * @return the Image types
+ */
+ Class[] getSupportedImageClasses();
+}
diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java
index 56504ff53..e4ec41e0b 100644
--- a/src/java/org/apache/fop/render/PrintRenderer.java
+++ b/src/java/org/apache/fop/render/PrintRenderer.java
@@ -24,8 +24,6 @@ import java.awt.geom.Rectangle2D;
import java.util.List;
import java.util.Map;
-import org.w3c.dom.Document;
-
import org.apache.fop.area.Area;
import org.apache.fop.area.Trait;
import org.apache.fop.fonts.CustomFontCollection;
@@ -36,6 +34,7 @@ import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.w3c.dom.Document;
/** Abstract base class of "Print" type renderers. */
public abstract class PrintRenderer extends AbstractRenderer {
@@ -112,6 +111,14 @@ public abstract class PrintRenderer extends AbstractRenderer {
}
/**
+ * Instantiates a RendererContext for an image
+ * @return a newly created RendererContext.
+ */
+ protected RendererContext instantiateRendererContext() {
+ return new RendererContext(this, getMimeType());
+ }
+
+ /**
* Creates a RendererContext for an image.
* @param x the x coordinate (in millipoints)
* @param y the y coordinate (in millipoints)
@@ -122,8 +129,7 @@ public abstract class PrintRenderer extends AbstractRenderer {
*/
protected RendererContext createRendererContext(int x, int y, int width, int height,
Map foreignAttributes) {
- RendererContext context;
- context = new RendererContext(this, getMimeType());
+ RendererContext context = instantiateRendererContext();
context.setUserAgent(userAgent);
context.setProperty(RendererContextConstants.WIDTH,
diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java
index e4e234cd2..ac885a44b 100644
--- a/src/java/org/apache/fop/render/RendererContext.java
+++ b/src/java/org/apache/fop/render/RendererContext.java
@@ -20,10 +20,12 @@
package org.apache.fop.render;
//Java
+import java.util.Iterator;
import java.util.Map;
-//FOP
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.xmlgraphics.util.QName;
/**
* The Render Context for external handlers. This provides a rendering context
@@ -31,21 +33,28 @@ import org.apache.fop.apps.FOUserAgent;
* render target.
*/
public class RendererContext {
+ /** conversion-mode extension attribute */
+ protected static final QName CONVERSION_MODE = new QName(
+ ExtensionElementMapping.URI, null, "conversion-mode");
+
+ /** "bitmap" value for the "conversion-mode" extension attribute. */
+ protected static final String BITMAP = "bitmap";
private final String mime;
private final AbstractRenderer renderer;
private FOUserAgent userAgent;
- private final Map props = new java.util.HashMap();
+
+ private final Map/*<String,Object>*/ props = new java.util.HashMap/*<String,Object>*/();
/**
- * Contructor for this class. It takes a MIME type as parameter.
+ * Constructor for this class. It takes a MIME type as parameter.
*
- * @param renderer The current renderer
- * @param m The MIME type of the output that's generated.
+ * @param renderer the current renderer
+ * @param mime the MIME type of the output that's generated.
*/
- public RendererContext(AbstractRenderer renderer, String m) {
+ public RendererContext(AbstractRenderer renderer, String mime) {
this.renderer = renderer;
- this.mime = m;
+ this.mime = mime;
}
/**
@@ -113,6 +122,19 @@ public class RendererContext {
return wrapper;
}
+ /** {@inheritDoc} **/
+ public String toString() {
+ StringBuffer stringBuffer = new StringBuffer("RendererContext{\n");
+ Iterator it = props.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String)it.next();
+ Object value = props.get(key);
+ stringBuffer.append("\t" + key + "=" + value + "\n");
+ }
+ stringBuffer.append("}");
+ return stringBuffer.toString();
+ }
+
/**
* Base class for a wrapper around RendererContext to access its properties in a type-safe,
* renderer-specific way.
diff --git a/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java b/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java
deleted file mode 100644
index 3b00804fc..000000000
--- a/src/java/org/apache/fop/render/afp/AFPAbstractImageFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.io.IOException;
-
-import org.apache.fop.afp.AFPDataObjectInfo;
-import org.apache.fop.afp.AFPForeignAttributeReader;
-import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPPaintingState;
-import org.apache.fop.afp.AFPResourceInfo;
-import org.apache.fop.afp.AFPUnitConverter;
-
-
-/**
- * Abstract image configurator
- */
-public abstract class AFPAbstractImageFactory {
- private static final int X = 0;
- private static final int Y = 1;
-
- /** the AFP state */
- protected final AFPPaintingState state;
-
- /** foreign attribute reader */
- private final AFPForeignAttributeReader foreignAttributeReader
- = new AFPForeignAttributeReader();
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPAbstractImageFactory(AFPPaintingState state) {
- this.state = state;
- }
-
- /**
- * Configures the data object info
- *
- * @param afpImageInfo the afp image info
- * @return the data object info
- * @throws IOException thrown if an I/O exception of some sort has occurred.
- */
- public AFPDataObjectInfo create(AFPRendererImageInfo afpImageInfo) throws IOException {
- AFPDataObjectInfo dataObjectInfo = createDataObjectInfo();
-
- // set resource information
- AFPResourceInfo resourceInfo
- = foreignAttributeReader.getResourceInfo(afpImageInfo.foreignAttributes);
- resourceInfo.setUri(afpImageInfo.uri);
- dataObjectInfo.setResourceInfo(resourceInfo);
-
- // set object area
- AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
- float srcX = afpImageInfo.origin.x + (float)afpImageInfo.pos.getX();
- float srcY = afpImageInfo.origin.y + (float)afpImageInfo.pos.getY();
- AFPUnitConverter unitConv = state.getUnitConverter();
- int[] coords = unitConv.mpts2units(new float[] {srcX, srcY});
- objectAreaInfo.setX(coords[X]);
- objectAreaInfo.setY(coords[Y]);
- int width = Math.round(unitConv.mpt2units((float)afpImageInfo.pos.getWidth()));
- objectAreaInfo.setWidth(width);
- int height = Math.round(unitConv.mpt2units((float)afpImageInfo.pos.getHeight()));
- objectAreaInfo.setHeight(height);
- dataObjectInfo.setObjectAreaInfo(objectAreaInfo);
- return dataObjectInfo;
- }
-
- /**
- * Creates the data object information object
- *
- * @return the data object information object
- */
- protected abstract AFPDataObjectInfo createDataObjectInfo();
-} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java b/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java
deleted file mode 100644
index aac17b701..000000000
--- a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoProvider.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.fop.afp.AFPPaintingState;
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
-import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
-
-/**
- * AFP data object info factory provider
- */
-public class AFPDataObjectInfoProvider {
-
- private final Map/*<AbstractImage,AFPDataObjectInfoFactory>*/ factoryMap
- = new java.util.HashMap/*<AbstractImage,AFPDataObjectInfoFactory>*/();
-
- private final AFPPaintingState state;
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPDataObjectInfoProvider(AFPPaintingState state) {
- this.state = state;
- init();
- }
-
- /**
- * Initialises the configurators
- */
- private void init() {
- factoryMap.put(
- ImageRendered.class, new AFPImageRenderedFactory(state));
- factoryMap.put(
- ImageRawCCITTFax.class, new AFPRawCCITTFaxFactory(state));
- factoryMap.put(
- ImageRawStream.class, new AFPImageRawStreamFactory(state));
- factoryMap.put(
- ImageGraphics2D.class, new AFPImageGraphics2DFactory(state));
- };
-
- /**
- * Returns the configurator for a given image
- *
- * @param img the image
- * @return the image configurator for the image
- */
- public AFPDataObjectInfoFactory getFactory(Image img) {
- Class clazz = img.getClass();
- AFPDataObjectInfoFactory configurator = (AFPDataObjectInfoFactory)factoryMap.get(clazz);
- // not directly matched so try to map ancestor
- if (configurator == null) {
- Iterator it = factoryMap.keySet().iterator();
- while (it.hasNext()) {
- Class imageClass = (Class)it.next();
- if (imageClass.isInstance(img)) {
- return (AFPDataObjectInfoFactory)factoryMap.get(imageClass);
- }
- }
- }
- return configurator;
- }
-}
diff --git a/src/java/org/apache/fop/afp/AFPForeignAttributeReader.java b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java
index 710c24533..2b5077fe9 100644
--- a/src/java/org/apache/fop/afp/AFPForeignAttributeReader.java
+++ b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java
@@ -17,13 +17,15 @@
/* $Id$ */
-package org.apache.fop.afp;
+package org.apache.fop.render.afp;
import java.io.File;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.AFPResourceInfo;
+import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.xmlgraphics.util.QName;
diff --git a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
index 4f92826cf..8e43d1c28 100644
--- a/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
+++ b/src/java/org/apache/fop/render/afp/AFPGraphics2DAdapter.java
@@ -28,7 +28,6 @@ import java.io.IOException;
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPGraphicsObjectInfo;
import org.apache.fop.afp.AFPPaintingState;
-import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
import org.apache.fop.render.AbstractGraphics2DAdapter;
import org.apache.fop.render.RendererContext;
@@ -40,95 +39,67 @@ import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
*/
public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter {
- private final AFPRenderer renderer;
-
- private final AFPGraphics2D g2d;
+ private final AFPPaintingState paintingState;
/**
* Main constructor
*
- * @param renderer the afp renderer
- */
- public AFPGraphics2DAdapter(AFPRenderer renderer) {
- this.renderer = renderer;
-
- final boolean textAsShapes = false;
- this.g2d = new AFPGraphics2D(textAsShapes);
- }
-
- /**
- * Returns the AFP graphics 2D implementation
- *
- * @return the AFP graphics 2D implementation
+ * @param paintingState the AFP painting state
*/
- public AFPGraphics2D getGraphics2D() {
- return g2d;
+ public AFPGraphics2DAdapter(AFPPaintingState paintingState) {
+ this.paintingState = paintingState;
}
/** {@inheritDoc} */
public void paintImage(Graphics2DImagePainter painter,
- RendererContext context,
+ RendererContext rendererContext,
int x, int y, int width, int height) throws IOException {
- AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(context);
-
- // set resource manager
- AFPResourceManager resourceManager = afpInfo.getResourceManager();
- g2d.setResourceManager(resourceManager);
-
- // set resource information
- AFPResourceInfo resourceInfo = afpInfo.getResourceInfo();
- g2d.setResourceInfo(resourceInfo);
+ AFPRendererContext afpRendererContext = (AFPRendererContext)rendererContext;
+ AFPInfo afpInfo = afpRendererContext.getInfo();
- // set painting state
- AFPPaintingState paintingState = afpInfo.getPaintingState();
- g2d.setPaintingState(paintingState);
-
- // set graphic context
- g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
-
- float fwidth = width / 1000f;
- float fheight = height / 1000f;
-
- // get the 'width' and 'height' attributes of the SVG document
- Dimension imageSize = painter.getImageSize();
- float imw = (float)imageSize.getWidth() / 1000f;
- float imh = (float)imageSize.getHeight() / 1000f;
- float sx = fwidth / imw;
- float sy = fheight / imh;
- AffineTransform at = new AffineTransform(sx, 0, 0, sy, x, y);
+ final boolean textAsShapes = false;
+ AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes);
- renderer.saveGraphicsState();
+ paintingState.push();
+ //Fallback solution: Paint to a BufferedImage
if (afpInfo.paintAsBitmap()) {
- //Fallback solution: Paint to a BufferedImage
- int resolution = Math.round(context.getUserAgent().getTargetResolution());
- RendererContextWrapper ctx = RendererContext.wrapRendererContext(context);
- BufferedImage bufferedImage = paintToBufferedImage(painter, ctx, resolution, false, false);
-
- AFPPaintingState state = afpInfo.getPaintingState();
- AffineTransform trans = state.getData().getTransform();
- float scale = AFPRenderer.NORMAL_AFP_RESOLUTION
- / context.getUserAgent().getTargetResolution();
- if (scale != 1) {
- at.scale(scale, scale);
- }
-
- if (!at.isIdentity()) {
- trans.concatenate(at);
- }
-
- g2d.drawImage(bufferedImage, trans, null);
+
+ // paint image
+ RendererContextWrapper rendererContextWrapper
+ = RendererContext.wrapRendererContext(rendererContext);
+ float targetResolution = rendererContext.getUserAgent().getTargetResolution();
+ int resolution = Math.round(targetResolution);
+ boolean colorImages = afpInfo.isColorSupported();
+ BufferedImage bufferedImage = paintToBufferedImage(
+ painter, rendererContextWrapper, resolution, !colorImages, false);
+
+ // draw image
+ AffineTransform at = paintingState.getData().getTransform();
+ at.translate(x, y);
+ g2d.drawImage(bufferedImage, at, null);
} else {
AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo();
graphicsObjectInfo.setPainter(painter);
graphicsObjectInfo.setGraphics2D(g2d);
+ // get the 'width' and 'height' attributes of the SVG document
+ Dimension imageSize = painter.getImageSize();
+ float imw = (float)imageSize.getWidth() / 1000f;
+ float imh = (float)imageSize.getHeight() / 1000f;
+
Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
graphicsObjectInfo.setArea(area);
+ AFPResourceManager resourceManager = afpInfo.getResourceManager();
resourceManager.createObject(graphicsObjectInfo);
}
- renderer.restoreGraphicsState();
+ paintingState.pop();
+ }
+
+ /** {@inheritDoc} */
+ protected int mpt2px(int unit, int resolution) {
+ return Math.round(paintingState.getUnitConverter().mpt2units(unit));
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java b/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
deleted file mode 100644
index 88c0b5c26..000000000
--- a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.awt.Rectangle;
-import java.awt.geom.AffineTransform;
-import java.io.IOException;
-
-import org.apache.batik.bridge.BridgeContext;
-import org.apache.fop.afp.AFPDataObjectInfo;
-import org.apache.fop.afp.AFPGraphics2D;
-import org.apache.fop.afp.AFPGraphicsObjectInfo;
-import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPPaintingState;
-import org.apache.fop.afp.AFPResourceInfo;
-import org.apache.fop.afp.AFPResourceLevel;
-import org.apache.fop.afp.AFPTextElementBridge;
-import org.apache.fop.afp.AFPTextHandler;
-import org.apache.fop.afp.AFPTextPainter;
-import org.apache.fop.render.RendererContext;
-import org.apache.fop.svg.SVGUserAgent;
-import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
-import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
-import org.apache.xmlgraphics.util.MimeConstants;
-
-
-/**
- * An AFP image graphics 2d factory
- */
-public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory {
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPImageGraphics2DFactory(AFPPaintingState state) {
- super(state);
- }
-
- /** {@inheritDoc} */
- protected AFPDataObjectInfo createDataObjectInfo() {
- return new AFPGraphicsObjectInfo();
- }
-
- /** {@inheritDoc} */
- public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
- AFPGraphicsObjectInfo graphicsObjectInfo
- = (AFPGraphicsObjectInfo)super.create(rendererImageInfo);
-
- AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo();
- // level not explicitly set/changed so default to inline for GOCA graphic objects
- // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) - hard copy works just fine)
- if (!resourceInfo.levelChanged()) {
- resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
- }
-
- // set mime type (unsupported by MOD:CA registry)
- graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA);
-
- // set graphics 2d
- AFPGraphics2DAdapter g2dAdapter = rendererImageInfo.getGraphics2DAdapter();
- AFPGraphics2D g2d = g2dAdapter.getGraphics2D();
- graphicsObjectInfo.setGraphics2D(g2d);
-
- // set resource, state and font info
- RendererContext rendererContext = rendererImageInfo.getRendererContext();
- AFPInfo afpInfo = AFPSVGHandler.getAFPInfo(rendererContext);
- g2d.setResourceManager(afpInfo.getResourceManager());
- g2d.setResourceInfo(afpInfo.getResourceInfo());
- g2d.setPaintingState(afpInfo.getPaintingState());
- g2d.setFontInfo(afpInfo.getFontInfo());
-
- // set to default graphic context
- g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
-
- // translate to current location
- AffineTransform at = state.getData().getTransform();
- g2d.translate(at.getTranslateX(), at.getTranslateY());
-
- // set afp state
- g2d.setPaintingState(state);
-
- // controls whether text painted by Batik is generated using text or path operations
- SVGUserAgent svgUserAgent
- = new SVGUserAgent(rendererContext.getUserAgent(), new AffineTransform());
- BridgeContext ctx = new BridgeContext(svgUserAgent);
- if (!afpInfo.strokeText()) {
- AFPTextHandler textHandler = new AFPTextHandler(g2d);
- g2d.setCustomTextHandler(textHandler);
- AFPTextPainter textPainter = new AFPTextPainter(textHandler);
- ctx.setTextPainter(textPainter);
- AFPTextElementBridge textElementBridge = new AFPTextElementBridge(textPainter);
- ctx.putBridge(textElementBridge);
- }
-
- // set painter
- ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage();
- Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter();
- graphicsObjectInfo.setPainter(painter);
-
- // set object area
- AFPObjectAreaInfo objectAreaInfo = graphicsObjectInfo.getObjectAreaInfo();
- int width = objectAreaInfo.getWidth();
- int height = objectAreaInfo.getHeight();
- Rectangle area = new Rectangle(width, height);
- graphicsObjectInfo.setArea(area);
-
- // invert y-axis for GOCA
- final int sx = 1;
- final int sy = -1;
- g2d.translate(0, height);
- g2d.scale(sx, sy);
-
- return graphicsObjectInfo;
- }
-
-}
diff --git a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java b/src/java/org/apache/fop/render/afp/AFPImageHandler.java
index ba2392835..8e925d460 100644
--- a/src/java/org/apache/fop/render/afp/AFPDataObjectInfoFactory.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandler.java
@@ -22,51 +22,39 @@ package org.apache.fop.render.afp;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import java.util.Map;
import org.apache.fop.afp.AFPDataObjectInfo;
-import org.apache.fop.afp.AFPForeignAttributeReader;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPUnitConverter;
+import org.apache.fop.render.ImageHandler;
-
-/**
- * Abstract image configurator
- */
-public abstract class AFPDataObjectInfoFactory {
+public abstract class AFPImageHandler implements ImageHandler {
private static final int X = 0;
private static final int Y = 1;
- /** the AFP painting state */
- protected final AFPPaintingState state;
-
/** foreign attribute reader */
private final AFPForeignAttributeReader foreignAttributeReader
= new AFPForeignAttributeReader();
/**
- * Main constructor
+ * Generates an intermediate AFPDataObjectInfo that is later used to construct
+ * the appropriate data object in the AFP DataStream.
*
- * @param state the AFP state
- */
- public AFPDataObjectInfoFactory(AFPPaintingState state) {
- this.state = state;
- }
-
- /**
- * Configures the data object info
- *
- * @param rendererImageInfo the afp image info
- * @return the data object info
+ * @param rendererImageInfo the renderer image info
+ * @return a data object info object
* @throws IOException thrown if an I/O exception of some sort has occurred.
*/
- public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
+ public AFPDataObjectInfo generateDataObjectInfo(
+ AFPRendererImageInfo rendererImageInfo) throws IOException {
AFPDataObjectInfo dataObjectInfo = createDataObjectInfo();
// set resource information
+ Map foreignAttributes = rendererImageInfo.getForeignAttributes();
AFPResourceInfo resourceInfo
- = foreignAttributeReader.getResourceInfo(rendererImageInfo.getForeignAttributes());
+ = foreignAttributeReader.getResourceInfo(foreignAttributes);
resourceInfo.setUri(rendererImageInfo.getURI());
dataObjectInfo.setResourceInfo(resourceInfo);
@@ -77,7 +65,12 @@ public abstract class AFPDataObjectInfoFactory {
Rectangle2D position = rendererImageInfo.getPosition();
float srcX = origin.x + (float)position.getX();
float srcY = origin.y + (float)position.getY();
- AFPUnitConverter unitConv = state.getUnitConverter();
+
+ AFPRendererContext rendererContext
+ = (AFPRendererContext)rendererImageInfo.getRendererContext();
+ AFPInfo afpInfo = rendererContext.getInfo();
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ AFPUnitConverter unitConv = paintingState.getUnitConverter();
int[] coords = unitConv.mpts2units(new float[] {srcX, srcY});
objectAreaInfo.setX(coords[X]);
objectAreaInfo.setY(coords[Y]);
@@ -88,11 +81,11 @@ public abstract class AFPDataObjectInfoFactory {
int height = Math.round(unitConv.mpt2units((float)position.getHeight()));
objectAreaInfo.setHeight(height);
- int resolution = state.getResolution();
+ int resolution = paintingState.getResolution();
objectAreaInfo.setHeightRes(resolution);
objectAreaInfo.setWidthRes(resolution);
- objectAreaInfo.setRotation(state.getRotation());
+ objectAreaInfo.setRotation(paintingState.getRotation());
dataObjectInfo.setObjectAreaInfo(objectAreaInfo);
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java
new file mode 100644
index 000000000..e8fe1f4f1
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerGraphics2D.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.geom.AffineTransform;
+import java.io.IOException;
+
+import org.apache.fop.afp.AFPDataObjectInfo;
+import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.afp.AFPGraphicsObjectInfo;
+import org.apache.fop.afp.AFPObjectAreaInfo;
+import org.apache.fop.afp.AFPPaintingState;
+import org.apache.fop.afp.AFPResourceInfo;
+import org.apache.fop.afp.AFPResourceLevel;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+import org.apache.xmlgraphics.util.MimeConstants;
+
+/**
+ * PDFImageHandler implementation which handles Graphics2D images.
+ */
+public class AFPImageHandlerGraphics2D extends AFPImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+ ImageFlavor.GRAPHICS2D
+ };
+
+ private static final Class[] CLASSES = new Class[] {
+ ImageGraphics2D.class
+ };
+
+ /** {@inheritDoc} */
+ public AFPDataObjectInfo generateDataObjectInfo(
+ AFPRendererImageInfo rendererImageInfo) throws IOException {
+
+ AFPRendererContext rendererContext = (AFPRendererContext)rendererImageInfo.getRendererContext();
+ AFPInfo afpInfo = rendererContext.getInfo();
+ ImageGraphics2D imageG2D = (ImageGraphics2D)rendererImageInfo.getImage();
+ Graphics2DImagePainter painter = imageG2D.getGraphics2DImagePainter();
+
+ if (afpInfo.paintAsBitmap()) {
+ int x = afpInfo.getX();
+ int y = afpInfo.getY();
+ int width = afpInfo.getWidth();
+ int height = afpInfo.getHeight();
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ AFPGraphics2DAdapter g2dAdapter = new AFPGraphics2DAdapter(paintingState);
+ g2dAdapter.paintImage(painter, rendererContext, x, y, width, height);
+ return null;
+ } else {
+ AFPGraphicsObjectInfo graphicsObjectInfo
+ = (AFPGraphicsObjectInfo)super.generateDataObjectInfo(rendererImageInfo);
+
+ AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo();
+ //level not explicitly set/changed so default to inline for GOCA graphic objects
+ // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) - hard copy works just fine)
+ if (!resourceInfo.levelChanged()) {
+ resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
+ }
+
+ // set mime type (unsupported by MOD:CA registry)
+ graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA);
+
+ // set g2d
+ boolean textAsShapes = false;
+
+ AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes);
+
+ graphicsObjectInfo.setGraphics2D(g2d);
+
+ // translate to current location
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ AffineTransform at = paintingState.getData().getTransform();
+ g2d.translate(at.getTranslateX(), at.getTranslateY());
+
+ // set painter
+ graphicsObjectInfo.setPainter(painter);
+
+ // invert y-axis for GOCA
+ final int sx = 1;
+ final int sy = -1;
+ AFPObjectAreaInfo objectAreaInfo = graphicsObjectInfo.getObjectAreaInfo();
+ int height = objectAreaInfo.getHeight();
+ g2d.translate(0, height);
+ g2d.scale(sx, sy);
+
+ return graphicsObjectInfo;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 200;
+ }
+
+ /** {@inheritDoc} */
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+ /** {@inheritDoc} */
+ protected AFPDataObjectInfo createDataObjectInfo() {
+ return new AFPGraphicsObjectInfo();
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java
index 2e6eca6ae..aa91bb660 100644
--- a/src/java/org/apache/fop/render/afp/AFPRawCCITTFaxFactory.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawCCITTFax.java
@@ -24,36 +24,39 @@ import java.io.IOException;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
-import org.apache.fop.afp.AFPPaintingState;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
/**
- * An CITT fax image data object info factory
+ * PDFImageHandler implementation which handles CCITT encoded images (CCITT fax group 3/4).
*/
-public class AFPRawCCITTFaxFactory extends AFPDataObjectInfoFactory {
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPRawCCITTFaxFactory(AFPPaintingState state) {
- super(state);
- }
+public class AFPImageHandlerRawCCITTFax extends AFPImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+ ImageFlavor.RAW_CCITTFAX,
+ };
+
+ private static final Class[] CLASSES = new Class[] {
+ ImageRawCCITTFax.class,
+ };
/** {@inheritDoc} */
- public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
- AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)super.create(rendererImageInfo);
+ public AFPDataObjectInfo generateDataObjectInfo(
+ AFPRendererImageInfo rendererImageInfo) throws IOException {
+ AFPImageObjectInfo imageObjectInfo
+ = (AFPImageObjectInfo)super.generateDataObjectInfo(rendererImageInfo);
- ImageRawCCITTFax ccitt = (ImageRawCCITTFax) rendererImageInfo.img;
+ ImageRawCCITTFax ccitt = (ImageRawCCITTFax) rendererImageInfo.getImage();
imageObjectInfo.setCompression(ccitt.getCompression());
AFPObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo();
- int xresol = (int) (ccitt.getSize().getDpiHorizontal() * 10);
- objectAreaInfo.setWidthRes(xresol);
+ ImageSize imageSize = ccitt.getSize();
+ int widthRes = (int) (imageSize.getDpiHorizontal() * 10);
+ objectAreaInfo.setWidthRes(widthRes);
- int yresol = (int) (ccitt.getSize().getDpiVertical() * 10);
- objectAreaInfo.setHeightRes(yresol);
+ int heightRes = (int) (imageSize.getDpiVertical() * 10);
+ objectAreaInfo.setHeightRes(heightRes);
imageObjectInfo.setInputStream(ccitt.createInputStream());
@@ -64,4 +67,20 @@ public class AFPRawCCITTFaxFactory extends AFPDataObjectInfoFactory {
protected AFPDataObjectInfo createDataObjectInfo() {
return new AFPImageObjectInfo();
}
-} \ No newline at end of file
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 400;
+ }
+
+ /** {@inheritDoc} */
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
index 376bee7b9..47344b200 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageRawStreamFactory.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
@@ -25,35 +25,48 @@ import java.io.InputStream;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawEPS;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
/**
- * A raw stream image data object info factory
+ * AFPImageHandler implementation which handles raw stream images.
*/
-public class AFPImageRawStreamFactory extends AFPDataObjectInfoFactory {
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPImageRawStreamFactory(AFPPaintingState state) {
- super(state);
- }
+public class AFPImageHandlerRawStream extends AFPImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+ ImageFlavor.RAW_JPEG,
+ ImageFlavor.RAW_CCITTFAX,
+ ImageFlavor.RAW_EPS,
+ };
+
+ private static final Class[] CLASSES = new Class[] {
+ ImageRawJPEG.class,
+ ImageRawCCITTFax.class,
+ ImageRawEPS.class
+ };
/** {@inheritDoc} */
- public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
- AFPDataObjectInfo dataObjectInfo = super.create(rendererImageInfo);
+ public AFPDataObjectInfo generateDataObjectInfo(
+ AFPRendererImageInfo rendererImageInfo) throws IOException {
+ AFPDataObjectInfo dataObjectInfo = super.generateDataObjectInfo(rendererImageInfo);
ImageInfo imageInfo = rendererImageInfo.getImageInfo();
String mimeType = imageInfo.getMimeType();
if (mimeType != null) {
dataObjectInfo.setMimeType(mimeType);
}
ImageRawStream rawStream = (ImageRawStream) rendererImageInfo.getImage();
- int resolution = state.getResolution();
AFPObjectAreaInfo objectAreaInfo = dataObjectInfo.getObjectAreaInfo();
+
+ AFPRendererContext rendererContext
+ = (AFPRendererContext)rendererImageInfo.getRendererContext();
+ AFPInfo afpInfo = rendererContext.getInfo();
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ int resolution = paintingState.getResolution();
objectAreaInfo.setWidthRes(resolution);
objectAreaInfo.setHeightRes(resolution);
@@ -69,6 +82,21 @@ public class AFPImageRawStreamFactory extends AFPDataObjectInfoFactory {
}
/** {@inheritDoc} */
+ public int getPriority() {
+ return 100;
+ }
+
+ /** {@inheritDoc} */
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+ /** {@inheritDoc} */
protected AFPDataObjectInfo createDataObjectInfo() {
return new AFPDataObjectInfo();
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java
new file mode 100644
index 000000000..59ca6cf38
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRegistry.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import org.apache.fop.render.AbstractImageHandlerRegistry;
+
+/**
+ * This class holds references to various image handlers used by the AFP renderer. It also
+ * supports automatic discovery of additional handlers available through
+ * the class path.
+ */
+public class AFPImageHandlerRegistry extends AbstractImageHandlerRegistry {
+
+ /**
+ * Main constructor
+ */
+ public AFPImageHandlerRegistry() {
+ }
+
+ /** {@inheritDoc} */
+ public Class getHandlerClass() {
+ return AFPImageHandler.class;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
index 59d6af9a8..ef6a6bb65 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageRenderedFactory.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
@@ -27,33 +27,41 @@ import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageBuffered;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.util.MimeConstants;
/**
- * A buffered image data object info factory
+ * PDFImageHandler implementation which handles RenderedImage instances.
*/
-public class AFPImageRenderedFactory extends AFPDataObjectInfoFactory {
-
- /**
- * Main constructor
- *
- * @param state the AFP painting state
- */
- public AFPImageRenderedFactory(AFPPaintingState state) {
- super(state);
- }
+public class AFPImageHandlerRenderedImage extends AFPImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+ ImageFlavor.BUFFERED_IMAGE,
+ ImageFlavor.RENDERED_IMAGE
+ };
+
+ private static final Class[] CLASSES = new Class[] {
+ ImageBuffered.class,
+ ImageRendered.class
+ };
/** {@inheritDoc} */
- public AFPDataObjectInfo create(AFPRendererImageInfo rendererImageInfo) throws IOException {
+ public AFPDataObjectInfo generateDataObjectInfo(
+ AFPRendererImageInfo rendererImageInfo) throws IOException {
AFPImageObjectInfo imageObjectInfo
- = (AFPImageObjectInfo)super.create(rendererImageInfo);
+ = (AFPImageObjectInfo)super.generateDataObjectInfo(rendererImageInfo);
imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
AFPObjectAreaInfo objectAreaInfo = imageObjectInfo.getObjectAreaInfo();
- int resolution = state.getResolution();
+ AFPRendererContext rendererContext
+ = (AFPRendererContext)rendererImageInfo.getRendererContext();
+ AFPInfo afpInfo = rendererContext.getInfo();
+ AFPPaintingState paintingState = afpInfo.getPaintingState();
+ int resolution = paintingState.getResolution();
objectAreaInfo.setWidthRes(resolution);
objectAreaInfo.setHeightRes(resolution);
@@ -70,13 +78,13 @@ public class AFPImageRenderedFactory extends AFPDataObjectInfoFactory {
ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos);
byte[] imageData = baos.toByteArray();
- boolean colorImages = state.isColorImages();
+ boolean colorImages = paintingState.isColorImages();
imageObjectInfo.setColor(colorImages);
// convert to grayscale
if (!colorImages) {
baos.reset();
- int bitsPerPixel = state.getBitsPerPixel();
+ int bitsPerPixel = paintingState.getBitsPerPixel();
imageObjectInfo.setBitsPerPixel(bitsPerPixel);
ImageEncodingHelper.encodeRGBAsGrayScale(
imageData, dataWidth, dataHeight, bitsPerPixel, baos);
@@ -91,4 +99,20 @@ public class AFPImageRenderedFactory extends AFPDataObjectInfoFactory {
protected AFPDataObjectInfo createDataObjectInfo() {
return new AFPImageObjectInfo();
}
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 300;
+ }
+
+ /** {@inheritDoc} */
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java
new file mode 100644
index 000000000..fee355da7
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerXML.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.fop.afp.AFPDataObjectInfo;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContextConstants;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.w3c.dom.Document;
+
+/**
+ * PDFImageHandler implementation which handles XML-based images.
+ */
+public class AFPImageHandlerXML extends AFPImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
+ ImageFlavor.XML_DOM,
+ };
+
+ private static final Class[] CLASSES = new Class[] {
+ ImageXMLDOM.class,
+ };
+
+ /** {@inheritDoc} */
+ public AFPDataObjectInfo generateDataObjectInfo(RendererContext context, Image image,
+ Point origin, Rectangle pos)
+ throws IOException {
+ AFPRenderer renderer = (AFPRenderer)context.getRenderer();
+ ImageXMLDOM imgXML = (ImageXMLDOM)image;
+ Document doc = imgXML.getDocument();
+ String ns = imgXML.getRootNamespace();
+ Map foreignAttributes = (Map)context.getProperty(
+ RendererContextConstants.FOREIGN_ATTRIBUTES);
+ renderer.renderDocument(doc, ns, pos, foreignAttributes);
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 400;
+ }
+
+ /** {@inheritDoc} */
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+ /** {@inheritDoc} */
+ protected AFPDataObjectInfo createDataObjectInfo() {
+ return null;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPInfo.java b/src/java/org/apache/fop/render/afp/AFPInfo.java
index 1059014ab..59050b66d 100644
--- a/src/java/org/apache/fop/render/afp/AFPInfo.java
+++ b/src/java/org/apache/fop/render/afp/AFPInfo.java
@@ -20,6 +20,7 @@
package org.apache.fop.render.afp;
import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
@@ -47,18 +48,18 @@ public final class AFPInfo {
/** see AFP_FONT_INFO */
private FontInfo fontInfo;
- /** See AFP_STATE */
- private AFPPaintingState state;
+ /** See AFP_PAINTING_STATE */
+ private AFPPaintingState paintingState;
/** See AFP_RESOURCE_MANAGER */
private AFPResourceManager resourceManager;
+ /** See AFP_RESOURCE_INFO */
+ private AFPResourceInfo resourceInfo;
+
/** true if SVG should be rendered as a bitmap instead of natively */
private boolean paintAsBitmap;
- /** the resource information */
- private AFPResourceInfo resourceInfo;
-
/**
* Returns the width.
*
@@ -128,7 +129,7 @@ public final class AFPInfo {
* @return the current AFP state
*/
public AFPPaintingState getPaintingState() {
- return this.state;
+ return this.paintingState;
}
/**
@@ -217,7 +218,7 @@ public final class AFPInfo {
* @param state the AFP state
*/
public void setPaintingState(AFPPaintingState state) {
- this.state = state;
+ this.paintingState = state;
}
/**
@@ -278,6 +279,19 @@ public final class AFPInfo {
return resourceInfo;
}
+ /**
+ * Creates an AFPGraphics2D implementation
+ *
+ * @param textAsShapes true when text is painted as shapes
+ * @return a newly created AFPGraphics2D
+ */
+ public AFPGraphics2D createGraphics2D(boolean textAsShapes) {
+ AFPGraphics2D g2d = new AFPGraphics2D(
+ textAsShapes, paintingState, resourceManager, resourceInfo, fontInfo);
+ g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
+ return g2d;
+ }
+
/** {@inheritDoc} */
public String toString() {
return "AFPInfo{width=" + width
@@ -287,7 +301,7 @@ public final class AFPInfo {
+ ", cfg=" + handlerConfiguration
+ ", fontInfo=" + fontInfo
+ ", resourceManager=" + resourceManager
- + ", state=" + state
+ + ", paintingState=" + paintingState
+ ", paintAsBitmap=" + paintAsBitmap
+ ", resourceInfo=" + resourceInfo
+ "}";
diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java
index 87c098a89..ede556ecb 100644
--- a/src/java/org/apache/fop/render/afp/AFPRenderer.java
+++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java
@@ -36,7 +36,6 @@ import java.util.Map;
import org.apache.fop.afp.AFPBorderPainter;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.AFPDataObjectInfo;
-import org.apache.fop.afp.AFPPageFonts;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPRectanglePainter;
import org.apache.fop.afp.AFPResourceManager;
@@ -47,6 +46,7 @@ import org.apache.fop.afp.RectanglePaintInfo;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontAttributes;
import org.apache.fop.afp.fonts.AFPFontCollection;
+import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.afp.modca.DataStream;
import org.apache.fop.afp.modca.PageObject;
import org.apache.fop.apps.FOPException;
@@ -77,7 +77,6 @@ import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
@@ -137,35 +136,33 @@ import org.apache.xmlgraphics.ps.ImageEncodingHelper;
*/
public class AFPRenderer extends AbstractPathOrientedRenderer {
- /** Normal PDF resolution (72dpi) */
- public static final int NORMAL_AFP_RESOLUTION = 72;
-
private static final int X = 0;
private static final int Y = 1;
- /** resource manager */
+ /** the resource manager */
private AFPResourceManager resourceManager;
- /** painting state */
+ /** the painting state */
private final AFPPaintingState paintingState;
/** unit converter */
private final AFPUnitConverter unitConv;
- /** line painter */
+ /** the line painter */
private AFPBorderPainter borderPainter;
- /** The map of page segments */
- private final Map/*<String,String>*/pageSegmentMap = new java.util.HashMap/*<String,String>*/();
+ /** the map of page segments */
+ private final Map/*<String,String>*/pageSegmentMap
+ = new java.util.HashMap/*<String,String>*/();
- /** The map of saved incomplete pages */
+ /** the map of saved incomplete pages */
private final Map pages = new java.util.HashMap/*<PageViewport,PageObject>*/();
- /** the afp datastream */
+ /** the AFP datastream */
private DataStream dataStream;
- /** data object information factory */
- private final AFPDataObjectInfoProvider dataObjectInfoProvider;
+ /** the image handler registry */
+ private final AFPImageHandlerRegistry imageHandlerRegistry;
private AFPRectanglePainter rectanglePainter;
@@ -176,7 +173,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
super();
this.resourceManager = new AFPResourceManager();
this.paintingState = new AFPPaintingState();
- this.dataObjectInfoProvider = new AFPDataObjectInfoProvider(paintingState);
+ this.imageHandlerRegistry = new AFPImageHandlerRegistry();
this.unitConv = paintingState.getUnitConverter();
}
@@ -252,7 +249,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
/** {@inheritDoc} */
public Graphics2DAdapter getGraphics2DAdapter() {
- return new AFPGraphics2DAdapter(this);
+ return new AFPGraphics2DAdapter(paintingState);
}
/** {@inheritDoc} */
@@ -380,6 +377,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
}
/** {@inheritDoc} */
+ protected RendererContext instantiateRendererContext() {
+ return new AFPRendererContext(this, getMimeType());
+ }
+
+ /** {@inheritDoc} */
protected RendererContext createRendererContext(int x, int y, int width,
int height, Map foreignAttributes) {
RendererContext context;
@@ -394,25 +396,34 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
}
private static final ImageFlavor[] NATIVE_FLAVORS = new ImageFlavor[] {
+ ImageFlavor.XML_DOM,
/*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP
- ImageFlavor.XML_DOM, ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
+ ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
- ImageFlavor.XML_DOM, ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
+ ImageFlavor.XML_DOM,
+ ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle2D pos, Map foreignAttributes) {
uri = URISpecification.getURL(uri);
paintingState.setImageUri(uri);
- Rectangle posInt = new Rectangle((int) pos.getX(), (int) pos.getY(),
- (int) pos.getWidth(), (int) pos.getHeight());
+
+ Point origin = new Point(currentIPPosition, currentBPPosition);
+ Rectangle posInt = new Rectangle(
+ (int)Math.round(pos.getX()),
+ (int)Math.round(pos.getY()),
+ (int)Math.round(pos.getWidth()),
+ (int)Math.round(pos.getHeight())
+ );
+ int x = origin.x + posInt.x;
+ int y = origin.y + posInt.y;
+
String name = (String)pageSegmentMap.get(uri);
- int x = currentIPPosition + posInt.x;
- int y = currentBPPosition + posInt.y;
- float[] srcPts = {x, y};
- int[] coords = unitConv.mpts2units(srcPts);
if (name != null) {
+ float[] srcPts = {x, y};
+ int[] coords = unitConv.mpts2units(srcPts);
dataStream.createIncludePageSegment(name, coords[X], coords[Y]);
} else {
ImageManager manager = userAgent.getFactory().getImageManager();
@@ -425,41 +436,40 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
// Only now fully load/prepare the image
Map hints = ImageUtil.getDefaultHints(sessionContext);
- ImageFlavor[] flavors = paintingState.isNativeImages() ? NATIVE_FLAVORS : FLAVORS;
+ boolean nativeImagesSupported = paintingState.isNativeImagesSupported();
+ ImageFlavor[] flavors = nativeImagesSupported ? NATIVE_FLAVORS : FLAVORS;
+
+ // Load image
org.apache.xmlgraphics.image.loader.Image img = manager.getImage(
info, flavors, hints, sessionContext);
- Point origin = new Point(currentIPPosition, currentBPPosition);
- AFPDataObjectInfoFactory factory = dataObjectInfoProvider.getFactory(img);
- if (factory != null) {
- AFPRendererImageInfo afpImageInfo
- = new AFPRendererImageInfo(uri, pos, origin, info, img, foreignAttributes);
- if (factory instanceof AFPImageGraphics2DFactory) {
- RendererContext rendererContext = createRendererContext(
- x, y, posInt.width, posInt.height, foreignAttributes);
- afpImageInfo.setRendererContext(rendererContext);
- AFPGraphics2DAdapter g2dAdapter
- = (AFPGraphics2DAdapter)getGraphics2DAdapter();
- afpImageInfo.setGraphics2DAdapter(g2dAdapter);
- }
+ // Handle image
+ AFPImageHandler imageHandler
+ = (AFPImageHandler)imageHandlerRegistry.getHandler(img);
+ if (imageHandler != null) {
+ RendererContext rendererContext = createRendererContext(
+ x, y, posInt.width, posInt.height, foreignAttributes);
+ AFPRendererImageInfo rendererImageInfo = new AFPRendererImageInfo(
+ uri, pos, origin, info, img, rendererContext, foreignAttributes);
AFPDataObjectInfo dataObjectInfo = null;
try {
- dataObjectInfo = factory.create(afpImageInfo);
+ dataObjectInfo = imageHandler.generateDataObjectInfo(rendererImageInfo);
+ // Create image
+ if (dataObjectInfo != null) {
+ resourceManager.createObject(dataObjectInfo);
+ }
} catch (IOException ioe) {
ResourceEventProducer eventProducer
= ResourceEventProducer.Provider.get(userAgent.getEventBroadcaster());
eventProducer.imageWritingError(this, ioe);
throw ioe;
}
- resourceManager.createObject(dataObjectInfo);
- } else if (img instanceof ImageXMLDOM) {
- ImageXMLDOM imgXML = (ImageXMLDOM) img;
- renderDocument(imgXML.getDocument(), imgXML.getRootNamespace(),
- posInt, foreignAttributes);
} else {
throw new UnsupportedOperationException(
- "Unsupported image type: " + img);
+ "No AFPImageHandler available for image: "
+ + info + " (" + img.getClass().getName() + ")");
}
+
} catch (ImageException ie) {
ResourceEventProducer eventProducer = ResourceEventProducer.Provider
.get(userAgent.getEventBroadcaster());
@@ -546,29 +556,17 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
public void renderText(TextArea text) {
renderInlineAreaBackAndBorders(text);
+ // set font size
int fontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
paintingState.setFontSize(fontSize);
- String name = getInternalFontNameForArea(text);
- AFPFont font = (AFPFont)fontInfo.getFonts().get(name);
-
- // Set letterSpacing
- // float ls = fs.getLetterSpacing() / this.currentFontSize;
-
- // Create an AFPFontAttributes object from the current font details
- AFPFontAttributes fontAttributes
- = new AFPFontAttributes(name, font, fontSize);
-
+ // register font as necessary
+ String internalFontName = getInternalFontNameForArea(text);
+ AFPFont font = (AFPFont)fontInfo.getFonts().get(internalFontName);
AFPPageFonts pageFonts = paintingState.getPageFonts();
- if (!pageFonts.containsKey(fontAttributes.getFontKey())) {
- // Font not found on current page, so add the new one
- fontAttributes.setFontReference(paintingState.incrementPageFontCount());
- pageFonts.put(fontAttributes.getFontKey(), fontAttributes);
- } else {
- // Use the previously stored font attributes
- fontAttributes = (AFPFontAttributes)pageFonts.get(fontAttributes.getFontKey());
- }
+ AFPFontAttributes fontAttributes = pageFonts.registerFont(internalFontName, font, fontSize);
+ // create text data info
AFPTextDataInfo textDataInfo = new AFPTextDataInfo();
int fontReference = fontAttributes.getFontReference();
@@ -765,8 +763,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
* @param nativeImages
* native image support
*/
- public void setNativeImages(boolean nativeImages) {
- paintingState.setNativeImages(nativeImages);
+ public void setNativeImagesSupported(boolean nativeImages) {
+ paintingState.setNativeImagesSupported(nativeImages);
}
/**
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 6a59d27e3..532d45967 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -213,6 +213,12 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
return fontList;
}
+ /** images are converted to grayscale bitmapped IOCA */
+ private static final String IMAGES_MODE_GRAYSCALE = "b+w";
+
+ /** images are converted to color bitmapped IOCA */
+ private static final String IMAGES_MODE_COLOR = "color";
+
/**
* Configure the AFP renderer.
*
@@ -234,15 +240,21 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
// image information
Configuration imagesCfg = cfg.getChild("images");
- if (!"color".equalsIgnoreCase(imagesCfg.getAttribute("mode", "b+w"))) {
- afpRenderer.setColorImages(false);
- afpRenderer.setBitsPerPixel(imagesCfg.getAttributeAsInteger("bits-per-pixel", 8));
- } else {
+
+ // default to grayscale images
+ String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE);
+ if (IMAGES_MODE_COLOR.equals(imagesMode)) {
afpRenderer.setColorImages(true);
+ } else {
+ afpRenderer.setColorImages(false);
+ // default to 8 bits per pixel
+ int bitsPerPixel = imagesCfg.getAttributeAsInteger("bits-per-pixel", 8);
+ afpRenderer.setBitsPerPixel(bitsPerPixel);
}
- // images are embedded directly without conversion to bitmapped IOCA
- afpRenderer.setNativeImages(imagesCfg.getAttributeAsBoolean("native", false));
+ // native image support
+ boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", false);
+ afpRenderer.setNativeImagesSupported(nativeImageSupport);
// renderer resolution
Configuration rendererResolutionCfg = cfg.getChild("renderer-resolution", false);
@@ -269,16 +281,6 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator {
+ resourceGroupDest + "'");
}
}
-
- // TODO: provide support for different MO:DCA interchange sets
- // the MO:DCA interchange set in use (defaults to MO:DCA-L)
-// Configuration modcaCfg = cfg.getChild("modca", false);
-// if (modcaCfg != null) {
-// String interchangeSetString = cfg.getAttribute(
-// "interchange-set", InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2);
-// InterchangeSet interchangeSet = InterchangeSet.valueOf(interchangeSetString);
-// afpRenderer.getAFPDataStream().setInterchangeSet(interchangeSet);
-// }
}
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererContext.java b/src/java/org/apache/fop/render/afp/AFPRendererContext.java
new file mode 100644
index 000000000..8d544a7c4
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPRendererContext.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.afp.AFPPaintingState;
+import org.apache.fop.afp.AFPResourceInfo;
+import org.apache.fop.afp.AFPResourceLevel;
+import org.apache.fop.afp.AFPResourceManager;
+import org.apache.fop.render.AbstractRenderer;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.RendererContextConstants;
+
+public class AFPRendererContext extends RendererContext {
+
+ /**
+ * Main constructor
+ *
+ * @param renderer the current renderer
+ * @param mime the MIME type of the output that's generated.
+ */
+ public AFPRendererContext(AbstractRenderer renderer, String mime) {
+ super(renderer, mime);
+ }
+
+ /**
+ * Returns a new AFPInfo for this renderer context
+ *
+ * @return an AFPInfo for this renderer context
+ */
+ public AFPInfo getInfo() {
+ AFPInfo info = new AFPInfo();
+ info.setWidth(((Integer)getProperty(RendererContextConstants.WIDTH)).intValue());
+ info.setHeight(((Integer)getProperty(RendererContextConstants.HEIGHT)).intValue());
+ info.setX(((Integer)getProperty(RendererContextConstants.XPOS)).intValue());
+ info.setY(((Integer)getProperty(RendererContextConstants.YPOS)).intValue());
+ info.setHandlerConfiguration((Configuration)getProperty(
+ RendererContextConstants.HANDLER_CONFIGURATION));
+ info.setFontInfo((org.apache.fop.fonts.FontInfo)getProperty(
+ AFPRendererContextConstants.AFP_FONT_INFO));
+ info.setPaintingState((AFPPaintingState)getProperty(
+ AFPRendererContextConstants.AFP_PAINTING_STATE));
+ info.setResourceManager(((AFPResourceManager)getProperty(
+ AFPRendererContextConstants.AFP_RESOURCE_MANAGER)));
+
+ Map foreignAttributes = (Map)getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
+ if (foreignAttributes != null) {
+ String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE);
+ boolean paintAsBitmap = BITMAP.equalsIgnoreCase(conversionMode);
+ info.setPaintAsBitmap(paintAsBitmap);
+
+ AFPForeignAttributeReader foreignAttributeReader
+ = new AFPForeignAttributeReader();
+ AFPResourceInfo resourceInfo
+ = foreignAttributeReader.getResourceInfo(foreignAttributes);
+ // default to inline level if painted as GOCA
+ if (!resourceInfo.levelChanged() && !paintAsBitmap) {
+ resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
+ }
+ info.setResourceInfo(resourceInfo);
+ }
+ return info;
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java b/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java
index d4a14d3c2..0aa3eb6ab 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererImageInfo.java
@@ -50,9 +50,6 @@ public class AFPRendererImageInfo {
/** the image */
protected final Image img;
- /** the AFP graphics 2d adapter */
- protected AFPGraphics2DAdapter g2dAdapter;
-
/** the renderer context */
protected RendererContext rendererContext;
@@ -64,15 +61,17 @@ public class AFPRendererImageInfo {
* @param origin the current position
* @param info the image info
* @param img the image
+ * @param rendererContext the renderer context
* @param foreignAttributes the foreign attributes
*/
public AFPRendererImageInfo(String uri, Rectangle2D pos, Point origin,
- ImageInfo info, Image img, Map foreignAttributes) {
+ ImageInfo info, Image img, RendererContext rendererContext, Map foreignAttributes) {
this.uri = uri;
this.pos = pos;
this.origin = origin;
this.info = info;
this.img = img;
+ this.rendererContext = rendererContext;
this.foreignAttributes = foreignAttributes;
}
@@ -86,15 +85,6 @@ public class AFPRendererImageInfo {
}
/**
- * Sets the graphics 2d adapter
- *
- * @param adapter the graphics 2d adapter
- */
- public void setGraphics2DAdapter(AFPGraphics2DAdapter adapter) {
- this.g2dAdapter = adapter;
- }
-
- /**
* Returns the image info
*
* @return the image info
@@ -113,15 +103,6 @@ public class AFPRendererImageInfo {
}
/**
- * Returns the graphics 2D adapter
- *
- * @return the graphics 2D adapter
- */
- public AFPGraphics2DAdapter getGraphics2DAdapter() {
- return this.g2dAdapter;
- }
-
- /**
* Returns the renderer context
*
* @return the renderer context
diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
index 3bdab289c..2800686d9 100644
--- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
@@ -22,39 +22,32 @@ package org.apache.fop.render.afp;
// FOP
import java.awt.Dimension;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Dimension2D;
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.BridgeException;
-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.fop.afp.AFPForeignAttributeReader;
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.afp.AFPGraphicsObjectInfo;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
-import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceManager;
-import org.apache.fop.afp.AFPTextElementBridge;
-import org.apache.fop.afp.AFPTextHandler;
-import org.apache.fop.afp.AFPTextPainter;
import org.apache.fop.afp.AFPUnitConverter;
import org.apache.fop.afp.Graphics2DImagePainterGOCA;
+import org.apache.fop.afp.svg.AFPBridgeContext;
+import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fonts.FontInfo;
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.RendererContext.RendererContextWrapper;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+import org.apache.xmlgraphics.util.MimeConstants;
import org.w3c.dom.Document;
/**
@@ -74,177 +67,138 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
}
}
- /**
- * Get the AFP information from the render context.
- *
- * @param context the renderer context
- * @return the AFP information retrieved from the context
- */
- public static AFPInfo getAFPInfo(RendererContext context) {
- AFPInfo afpi = new AFPInfo();
- 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.setPaintingState((AFPPaintingState)context.getProperty(
- AFPRendererContextConstants.AFP_PAINTING_STATE));
- afpi.setResourceManager(((AFPResourceManager)context.getProperty(
- AFPRendererContextConstants.AFP_RESOURCE_MANAGER)));
-
- Map foreignAttributes = (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
- if (foreignAttributes != null) {
- String conversionMode = (String)foreignAttributes.get(CONVERSION_MODE);
- boolean paintAsBitmap = BITMAP.equalsIgnoreCase(conversionMode);
- afpi.setPaintAsBitmap(paintAsBitmap);
-
- AFPForeignAttributeReader foreignAttributeReader = new AFPForeignAttributeReader();
- AFPResourceInfo resourceInfo = foreignAttributeReader.getResourceInfo(foreignAttributes);
- // default to inline level if painted as GOCA
- if (!resourceInfo.levelChanged() && !paintAsBitmap) {
- resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
- }
- afpi.setResourceInfo(resourceInfo);
- }
- return afpi;
- }
-
private static final int X = 0;
private static final int Y = 1;
/**
* Render the SVG document.
*
- * @param context the renderer context
+ * @param rendererContext the renderer context
* @param doc the SVG document
* @throws IOException In case of an I/O error while painting the image
*/
- protected void renderSVGDocument(final RendererContext context,
+ protected void renderSVGDocument(final RendererContext rendererContext,
final Document doc) throws IOException {
- AFPInfo afpInfo = getAFPInfo(context);
+ AFPRendererContext afpRendererContext = (AFPRendererContext)rendererContext;
+ AFPInfo afpInfo = afpRendererContext.getInfo();
this.paintAsBitmap = afpInfo.paintAsBitmap();
+ FOUserAgent userAgent = rendererContext.getUserAgent();
+
// fallback paint as bitmap
+ String uri = getDocumentURI(doc);
if (paintAsBitmap) {
try {
- super.renderSVGDocument(context, doc);
+ super.renderSVGDocument(rendererContext, doc);
} catch (IOException ioe) {
SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
- context.getUserAgent().getEventBroadcaster());
- eventProducer.svgRenderingError(this, ioe, getDocumentURI(doc));
+ userAgent.getEventBroadcaster());
+ eventProducer.svgRenderingError(this, ioe, uri);
}
return;
}
- String uri = ((AbstractDocument)doc).getDocumentURI();
- AFPPaintingState paintingState = afpInfo.getPaintingState();
+ // Create a new AFPGraphics2D
+ final boolean textAsShapes = false;
+ AFPGraphics2D g2d = afpInfo.createGraphics2D(textAsShapes);
+
+ AFPPaintingState paintingState = g2d.getPaintingState();
paintingState.setImageUri(uri);
+ // Create an AFPBridgeContext
+ BridgeContext bridgeContext = createBridgeContext(userAgent, g2d);
+
+ // Build the SVG DOM and provide the painter with it
+ GraphicsNode root = buildGraphicsNode(userAgent, bridgeContext, doc);
+
+ // Create Graphics2DImagePainter
+ final RendererContextWrapper wrappedContext
+ = RendererContext.wrapRendererContext(rendererContext);
+ Dimension imageSize = getImageSize(wrappedContext);
+ Graphics2DImagePainter painter
+ = createGrapics2DImagePainter(bridgeContext, root, imageSize);
+
+ // Create AFPObjectAreaInfo
+ RendererContextWrapper rctx = RendererContext.wrapRendererContext(rendererContext);
+ int x = rctx.getCurrentXPosition();
+ int y = rctx.getCurrentYPosition();
+ int width = afpInfo.getWidth();
+ int height = afpInfo.getHeight();
+ int resolution = afpInfo.getResolution();
+
+ paintingState.push(); // save
+
+ AFPObjectAreaInfo objectAreaInfo
+ = createObjectAreaInfo(paintingState, x, y, width, height, resolution);
+
+ // Create AFPGraphicsObjectInfo
+ AFPResourceInfo resourceInfo = afpInfo.getResourceInfo();
+ AFPGraphicsObjectInfo graphicsObjectInfo = createGraphicsObjectInfo(
+ paintingState, painter, userAgent, resourceInfo, g2d);
+ graphicsObjectInfo.setObjectAreaInfo(objectAreaInfo);
+
+ // Create the GOCA GraphicsObject in the DataStream
+ AFPResourceManager resourceManager = afpInfo.getResourceManager();
+ resourceManager.createObject(graphicsObjectInfo);
+
+ paintingState.pop(); // resume
+ }
+
+ private AFPObjectAreaInfo createObjectAreaInfo(AFPPaintingState paintingState,
+ int x, int y, int width, int height, int resolution) {
// set the data object parameters
AFPObjectAreaInfo objectAreaInfo = new AFPObjectAreaInfo();
- RendererContextWrapper rctx = RendererContext.wrapRendererContext(context);
- int currx = rctx.getCurrentXPosition();
- int curry = rctx.getCurrentYPosition();
- float[] srcPts = {currx, curry};
-
- AFPUnitConverter unitConv = paintingState.getUnitConverter();
- int[] coords = unitConv.mpts2units(srcPts);
- objectAreaInfo.setX(coords[X]);
- objectAreaInfo.setY(coords[Y]);
+ AffineTransform at = paintingState.getData().getTransform();
+ at.translate(x, y);
+ objectAreaInfo.setX((int)Math.round(at.getTranslateX()));
+ objectAreaInfo.setY((int)Math.round(at.getTranslateY()));
- int resolution = afpInfo.getResolution();
objectAreaInfo.setWidthRes(resolution);
objectAreaInfo.setHeightRes(resolution);
- int width = Math.round(unitConv.mpt2units(afpInfo.getWidth()));
- objectAreaInfo.setWidth(width);
-
- int height = Math.round(unitConv.mpt2units(afpInfo.getHeight()));
- objectAreaInfo.setHeight(height);
+ AFPUnitConverter unitConv = paintingState.getUnitConverter();
+ objectAreaInfo.setWidth(Math.round(unitConv.mpt2units(width)));
+ objectAreaInfo.setHeight(Math.round(unitConv.mpt2units(height)));
int rotation = paintingState.getRotation();
objectAreaInfo.setRotation(rotation);
- AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo();
- graphicsObjectInfo.setUri(uri);
+ return objectAreaInfo;
+ }
- // Configure Graphics2D implementation
- final boolean textAsShapes = false;
- AFPGraphics2D g2d = new AFPGraphics2D(textAsShapes);
+ private AFPGraphicsObjectInfo createGraphicsObjectInfo(AFPPaintingState paintingState, Graphics2DImagePainter painter,
+ FOUserAgent userAgent, AFPResourceInfo resourceInfo, AFPGraphics2D g2d) {
+ AFPGraphicsObjectInfo graphicsObjectInfo = new AFPGraphicsObjectInfo();
- g2d.setPaintingState(paintingState);
+ String uri = paintingState.getImageUri();
+ graphicsObjectInfo.setUri(uri);
- AFPResourceManager resourceManager = afpInfo.getResourceManager();
- g2d.setResourceManager(resourceManager);
+ graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA);
- AFPResourceInfo resourceInfo = afpInfo.getResourceInfo();
- g2d.setResourceInfo(resourceInfo);
graphicsObjectInfo.setResourceInfo(resourceInfo);
- g2d.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
-
- FontInfo fontInfo = afpInfo.getFontInfo();
- g2d.setFontInfo(fontInfo);
-
- // Configure GraphicsObjectPainter with the Graphics2D implementation
- GraphicsObjectPainterAFP painter = new GraphicsObjectPainterAFP(g2d);
- (graphicsObjectInfo).setPainter(painter);
+ graphicsObjectInfo.setPainter(painter);
- // Controls whether text painted by Batik is generated using text or path operations
- SVGUserAgent svgUserAgent
- = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
- BridgeContext ctx = new BridgeContext(svgUserAgent);
- if (!afpInfo.strokeText()) {
- AFPTextHandler textHandler = new AFPTextHandler(g2d);
- g2d.setCustomTextHandler(textHandler);
- AFPTextPainter textPainter = new AFPTextPainter(textHandler);
- ctx.setTextPainter(textPainter);
- AFPTextElementBridge tBridge = new AFPTextElementBridge(textPainter);
- ctx.putBridge(tBridge);
- }
+ // Set the afp graphics 2d implementation
+ graphicsObjectInfo.setGraphics2D(g2d);
- // Build the SVG DOM and provide the painter with it
- GraphicsNode root;
- GVTBuilder builder = new GVTBuilder();
- try {
- root = builder.build(ctx, doc);
- painter.setGraphicsNode(root);
- } catch (BridgeException e) {
- SVGEventProducer eventProducer = SVGEventProducer.Provider.get(
- context.getUserAgent().getEventBroadcaster());
- eventProducer.svgNotBuilt(this, e, uri);
- return;
- }
+ return graphicsObjectInfo;
+ }
- // convert to afp inches
- Dimension2D dim = ctx.getDocumentSize();
- double w = dim.getWidth() * 1000f;
- double h = dim.getHeight() * 1000f;
- double wx = (afpInfo.getWidth() / w);
- double hx = (afpInfo.getHeight() / h);
- double scaleX = unitConv.pt2units((float)wx);
- double scaleY = unitConv.pt2units((float)hx);
- double yOffset = unitConv.mpt2units(afpInfo.getHeight());
-
- // Transformation matrix that establishes the local coordinate system
- // for the SVG graphic in relation to the current coordinate system
- // (note: y axis is inverted)
- AffineTransform trans = new AffineTransform(scaleX, 0, 0, -scaleY, 0, yOffset);
- g2d.setTransform(trans);
+ public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) {
+ ImageManager imageManager = userAgent.getFactory().getImageManager();
- // Set the afp graphics 2d implementation
- graphicsObjectInfo.setGraphics2D(g2d);
+ SVGUserAgent svgUserAgent
+ = new SVGUserAgent(userAgent, new AffineTransform());
- // Set the object area info
- graphicsObjectInfo.setObjectAreaInfo(objectAreaInfo);
+ ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
- // Create the graphics object
- resourceManager.createObject(graphicsObjectInfo);
+ FontInfo fontInfo = g2d.getFontInfo();
+ return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext,
+ new AffineTransform(), g2d);
}
/** {@inheritDoc} */
@@ -259,11 +213,13 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
}
/** {@inheritDoc} */
- protected Graphics2DImagePainter createPainter(BridgeContext ctx, GraphicsNode root, Dimension imageSize) {
+ protected Graphics2DImagePainter createGrapics2DImagePainter(BridgeContext ctx, GraphicsNode root, Dimension imageSize) {
Graphics2DImagePainter painter = null;
if (paintAsBitmap()) {
- painter = super.createPainter(root, ctx, imageSize);
+ // paint as IOCA Image
+ painter = super.createGraphics2DImagePainter(root, ctx, imageSize);
} else {
+ // paint as GOCA Graphics
painter = new Graphics2DImagePainterGOCA(root, ctx, imageSize);
}
return painter;
diff --git a/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java b/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java
deleted file mode 100644
index 7eb2c1001..000000000
--- a/src/java/org/apache/fop/render/afp/GraphicsObjectPainterAFP.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.afp.AFPGraphics2D;
-import org.apache.fop.afp.modca.GraphicsObject;
-import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
-
-/**
- * Paints SVG as a GOCA Graphics Object using Batik
- */
-public class GraphicsObjectPainterAFP implements Graphics2DImagePainter {
- /** Static logging instance */
- protected static Log log = LogFactory.getLog(GraphicsObjectPainterAFP.class);
-
- private final AFPGraphics2D graphics2D;
-
- /** the batik root node of the svg document */
- private GraphicsNode root;
-
- /**
- * Main constructor
- *
- * @param graphics an AFP graphics 2D implementation
- */
- public GraphicsObjectPainterAFP(AFPGraphics2D graphics) {
- final boolean textAsShapes = false;
- this.graphics2D = new AFPGraphics2D(textAsShapes);
- }
-
- /**
- * Sets the graphics node
- *
- * @param rootNode the graphics root node
- */
- public void setGraphicsNode(GraphicsNode rootNode) {
- this.root = rootNode;
- }
-
- /** {@inheritDoc} */
- public void paint(Graphics2D g2d, Rectangle2D area) {
- log.debug("Painting SVG using GOCA");
-
- // tell batik to paint the graphics object
- root.paint(g2d);
-
- // dispose of the graphics 2d implementation
- g2d.dispose();
- }
-
- /** {@inheritDoc} */
- public Dimension getImageSize() {
- return null;
- }
-
- /**
- * Sets the GOCA Graphics Object
- *
- * @param graphicsObject the GOCA Graphics Object
- */
- public void setGraphicsObject(GraphicsObject graphicsObject) {
- this.graphics2D.setGraphicsObject(graphicsObject);
- }
-
-}
diff --git a/src/java/org/apache/fop/render/afp/package.html b/src/java/org/apache/fop/render/afp/package.html
new file mode 100644
index 000000000..3e611d964
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/package.html
@@ -0,0 +1,23 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id: package.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
+<HTML>
+<TITLE>org.apache.fop.render.afp Package</TITLE>
+<BODY>
+<P>An AFP Renderer implementation and supporting classes.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java b/src/java/org/apache/fop/render/pdf/PDFImageHandler.java
index f93ee5a97..6343d0c50 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandler.java
@@ -23,36 +23,15 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageFlavor;
-
import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.RendererContext;
+import org.apache.xmlgraphics.image.loader.Image;
/**
* This interface is used for handling all sorts of image type for PDF output.
*/
-public interface PDFImageHandler {
-
- /**
- * Returns the priority for this image handler. A lower value means higher priority. This
- * information is used to build the ordered/prioritized list of supported ImageFlavors for
- * the PDF renderer. The built-in handlers use priorities between 100 and 999.
- * @return a positive integer (>0) indicating the priority
- */
- int getPriority();
-
- /**
- * Returns the {@link ImageFlavor}s supported by this instance
- * @return the supported image flavors
- */
- ImageFlavor[] getSupportedImageFlavors();
-
- /**
- * Returns the {@link Image} subclass supported by this instance.
- * @return the Image type
- */
- Class getSupportedImageClass();
+public interface PDFImageHandler extends ImageHandler {
/**
* Generates the PDF objects for the given {@link Image} instance. If the handler generates
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
index a58fe5922..9f44e58b5 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
@@ -23,13 +23,12 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
+import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.RendererContext;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
-import org.apache.fop.pdf.PDFXObject;
-import org.apache.fop.render.RendererContext;
-
/**
* PDFImageHandler implementation which handles Graphics2D images.
*/
@@ -39,6 +38,10 @@ public class PDFImageHandlerGraphics2D implements PDFImageHandler {
ImageFlavor.GRAPHICS2D,
};
+ private static final Class[] CLASSES = new Class[] {
+ ImageGraphics2D.class,
+ };
+
/** {@inheritDoc} */
public PDFXObject generateImage(RendererContext context, Image image,
Point origin, Rectangle pos)
@@ -56,8 +59,8 @@ public class PDFImageHandlerGraphics2D implements PDFImageHandler {
}
/** {@inheritDoc} */
- public Class getSupportedImageClass() {
- return ImageGraphics2D.class;
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java
index 9f56ebfea..158e93c86 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawCCITTFax.java
@@ -23,15 +23,14 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageFlavor;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
-
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFImage;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RendererContext;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
/**
* PDFImageHandler implementation which handles CCITT encoded images (CCITT fax group 3/4).
@@ -42,6 +41,10 @@ public class PDFImageHandlerRawCCITTFax implements PDFImageHandler {
ImageFlavor.RAW_CCITTFAX,
};
+ private static final Class[] CLASSES = new Class[] {
+ ImageRawCCITTFax.class,
+ };
+
/** {@inheritDoc} */
public PDFXObject generateImage(RendererContext context, Image image,
Point origin, Rectangle pos)
@@ -71,8 +74,8 @@ public class PDFImageHandlerRawCCITTFax implements PDFImageHandler {
}
/** {@inheritDoc} */
- public Class getSupportedImageClass() {
- return ImageRawCCITTFax.class;
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java
index f971a49ae..1432547da 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawJPEG.java
@@ -23,15 +23,14 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageFlavor;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
-
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFImage;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RendererContext;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
/**
* PDFImageHandler implementation which handles raw JPEG images.
@@ -42,6 +41,10 @@ public class PDFImageHandlerRawJPEG implements PDFImageHandler {
ImageFlavor.RAW_JPEG,
};
+ private static final Class[] CLASSES = new Class[] {
+ ImageRawJPEG.class,
+ };
+
/** {@inheritDoc} */
public PDFXObject generateImage(RendererContext context, Image image,
Point origin, Rectangle pos)
@@ -71,8 +74,8 @@ public class PDFImageHandlerRawJPEG implements PDFImageHandler {
}
/** {@inheritDoc} */
- public Class getSupportedImageClass() {
- return ImageRawJPEG.class;
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java
index b664a0a24..1d4c733a3 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRegistry.java
@@ -19,171 +19,18 @@
package org.apache.fop.render.pdf;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageFlavor;
-import org.apache.xmlgraphics.util.Service;
+import org.apache.fop.render.AbstractImageHandlerRegistry;
/**
* This class holds references to various image handlers used by the PDF renderer. It also
* supports automatic discovery of additional handlers available through
* the class path.
*/
-public class PDFImageHandlerRegistry {
-
- /** the logger */
- private static Log log = LogFactory.getLog(PDFImageHandlerRegistry.class);
-
- private static final Comparator HANDLER_COMPARATOR = new Comparator() {
- public int compare(Object o1, Object o2) {
- PDFImageHandler h1 = (PDFImageHandler)o1;
- PDFImageHandler h2 = (PDFImageHandler)o2;
- return h1.getPriority() - h2.getPriority();
- }
- };
-
- /** Map containing PDF image handlers for various MIME types */
- private Map handlers = new java.util.HashMap();
- /** List containing the same handlers as above but ordered by priority */
- private List handlerList = new java.util.LinkedList();
+public class PDFImageHandlerRegistry extends AbstractImageHandlerRegistry {
- /** Sorted Set of registered handlers */
- private ImageFlavor[] supportedFlavors = new ImageFlavor[0];
- private int handlerRegistrations;
- private int lastSync;
-
- /**
- * Default constructor.
- */
- public PDFImageHandlerRegistry() {
- discoverHandlers();
- }
-
- /**
- * Add an PDFImageHandler. The handler itself is inspected to find out what it supports.
- * @param classname the fully qualified class name
- */
- public void addHandler(String classname) {
- try {
- PDFImageHandler handlerInstance
- = (PDFImageHandler)Class.forName(classname).newInstance();
- addHandler(handlerInstance);
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("Could not find "
- + classname);
- } catch (InstantiationException e) {
- throw new IllegalArgumentException("Could not instantiate "
- + classname);
- } catch (IllegalAccessException e) {
- throw new IllegalArgumentException("Could not access "
- + classname);
- } catch (ClassCastException e) {
- throw new IllegalArgumentException(classname
- + " is not an "
- + PDFImageHandler.class.getName());
- }
+ /** {@inheritDoc} */
+ public Class getHandlerClass() {
+ return PDFImageHandler.class;
}
- /**
- * Add an image handler. The handler itself is inspected to find out what it supports.
- * @param handler the PDFImageHandler instance
- */
- public synchronized void addHandler(PDFImageHandler handler) {
- Class imageClass = handler.getSupportedImageClass();
- this.handlers.put(imageClass, handler);
-
- //Sorted insert
- ListIterator iter = this.handlerList.listIterator();
- while (iter.hasNext()) {
- PDFImageHandler h = (PDFImageHandler)iter.next();
- if (HANDLER_COMPARATOR.compare(handler, h) < 0) {
- iter.previous();
- break;
- }
- }
- iter.add(handler);
- this.handlerRegistrations++;
- }
-
- /**
- * Returns an PDFImageHandler which handles an specific image type given the MIME type
- * of the image.
- * @param img the Image to be handled
- * @return the PDFImageHandler responsible for handling the image or null if none is available
- */
- public PDFImageHandler getHandler(Image img) {
- return getHandler(img.getClass());
- }
-
- /**
- * Returns an PDFImageHandler which handles an specific image type given the MIME type
- * of the image.
- * @param imageClass the Image subclass for which to get a handler
- * @return the PDFImageHandler responsible for handling the image or null if none is available
- */
- protected synchronized PDFImageHandler getHandler(Class imageClass) {
- PDFImageHandler handler = null;
- Class cl = imageClass;
- while (cl != null) {
- handler = (PDFImageHandler)handlers.get(cl);
- if (handler != null) {
- break;
- }
- cl = cl.getSuperclass();
- }
- return handler;
- }
-
- /**
- * Returns the ordered array of supported image flavors.
- * @return the array of image flavors
- */
- public synchronized ImageFlavor[] getSupportedFlavors() {
- if (this.lastSync != this.handlerRegistrations) {
- //Extract all ImageFlavors into a single array
- List flavors = new java.util.ArrayList();
- Iterator iter = this.handlerList.iterator();
- while (iter.hasNext()) {
- ImageFlavor[] f = ((PDFImageHandler)iter.next()).getSupportedImageFlavors();
- for (int i = 0; i < f.length; i++) {
- flavors.add(f[i]);
- }
- }
- this.supportedFlavors = (ImageFlavor[])flavors.toArray(new ImageFlavor[flavors.size()]);
- this.lastSync = this.handlerRegistrations;
- }
- return this.supportedFlavors;
- }
-
- /**
- * Discovers PDFImageHandler implementations through the classpath and dynamically
- * registers them.
- */
- private void discoverHandlers() {
- // add mappings from available services
- Iterator providers = Service.providers(PDFImageHandler.class);
- if (providers != null) {
- while (providers.hasNext()) {
- PDFImageHandler handler = (PDFImageHandler)providers.next();
- try {
- if (log.isDebugEnabled()) {
- log.debug("Dynamically adding PDFImageHandler: "
- + handler.getClass().getName());
- }
- addHandler(handler);
- } catch (IllegalArgumentException e) {
- log.error("Error while adding PDFImageHandler", e);
- }
-
- }
- }
- }
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java
index 783cb225c..edbe9005d 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRenderedImage.java
@@ -23,15 +23,14 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageFlavor;
-import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
-
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFImage;
import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RendererContext;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
/**
* PDFImageHandler implementation which handles RenderedImage instances.
@@ -43,6 +42,11 @@ public class PDFImageHandlerRenderedImage implements PDFImageHandler {
ImageFlavor.RENDERED_IMAGE
};
+ private static final Class[] CLASSES = new Class[] {
+ ImageRendered.class,
+ };
+
+
/** {@inheritDoc} */
public PDFXObject generateImage(RendererContext context, Image image,
Point origin, Rectangle pos)
@@ -72,8 +76,8 @@ public class PDFImageHandlerRenderedImage implements PDFImageHandler {
}
/** {@inheritDoc} */
- public Class getSupportedImageClass() {
- return ImageRendered.class;
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java
index d111e733f..069fef172 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerXML.java
@@ -24,14 +24,12 @@ import java.awt.Rectangle;
import java.io.IOException;
import java.util.Map;
-import org.w3c.dom.Document;
-
+import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.RendererContext;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
-
-import org.apache.fop.pdf.PDFXObject;
-import org.apache.fop.render.RendererContext;
+import org.w3c.dom.Document;
/**
* PDFImageHandler implementation which handles XML-based images.
@@ -42,6 +40,10 @@ public class PDFImageHandlerXML implements PDFImageHandler {
ImageFlavor.XML_DOM,
};
+ private static final Class[] CLASSES = new Class[] {
+ ImageXMLDOM.class,
+ };
+
/** {@inheritDoc} */
public PDFXObject generateImage(RendererContext context, Image image,
Point origin, Rectangle pos)
@@ -62,8 +64,8 @@ public class PDFImageHandlerXML implements PDFImageHandler {
}
/** {@inheritDoc} */
- public Class getSupportedImageClass() {
- return ImageXMLDOM.class;
+ public Class[] getSupportedImageClasses() {
+ return CLASSES;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 0eba2fe91..ba3d89195 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -1658,7 +1658,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
info, imageHandlerRegistry.getSupportedFlavors(), hints, sessionContext);
//First check for a dynamically registered handler
- PDFImageHandler handler = imageHandlerRegistry.getHandler(img.getClass());
+ PDFImageHandler handler
+ = (PDFImageHandler)imageHandlerRegistry.getHandler(img.getClass());
if (handler != null) {
if (log.isDebugEnabled()) {
log.debug("Using PDFImageHandler: " + handler.getClass().getName());
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index 7c525dbf7..a318c6465 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -19,40 +19,34 @@
package org.apache.fop.render.ps;
+import java.awt.Color;
import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.TextAttribute;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-/* java.awt.Font is not imported to avoid confusion with
- org.apache.fop.fonts.Font */
-
+import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
-import java.awt.font.TextAttribute;
-import java.awt.Shape;
-import java.awt.Paint;
-import java.awt.Stroke;
-import java.awt.Color;
-import java.io.IOException;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
+import org.apache.batik.dom.svg.SVGOMTextElement;
+import org.apache.batik.gvt.TextNode;
+import org.apache.batik.gvt.TextPainter;
+import org.apache.batik.gvt.font.GVTFontFamily;
+import org.apache.batik.gvt.renderer.StrokingTextPainter;
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
+import org.apache.batik.gvt.text.Mark;
+import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
-
import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
-import org.apache.xmlgraphics.java2d.TextHandler;
-
-import org.apache.batik.dom.svg.SVGOMTextElement;
-import org.apache.batik.gvt.text.Mark;
-import org.apache.batik.gvt.TextPainter;
-import org.apache.batik.gvt.TextNode;
-import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
-import org.apache.batik.gvt.text.TextPaintInfo;
-import org.apache.batik.gvt.font.GVTFontFamily;
-import org.apache.batik.gvt.renderer.StrokingTextPainter;
/**
@@ -74,8 +68,8 @@ public class PSTextPainter implements TextPainter {
/** the logger for this class */
protected Log log = LogFactory.getLog(PSTextPainter.class);
- private NativeTextHandler nativeTextHandler;
- private FontInfo fontInfo;
+ private final NativeTextHandler nativeTextHandler;
+ private final FontInfo fontInfo;
/**
* Use the stroking text painter to get the bounds and shape.
@@ -317,7 +311,7 @@ public class PSTextPainter implements TextPainter {
}
drawPrimitiveString(g2d, loc, font, txt, tx);
- loc.setLocation(loc.getX() + (double)advance, loc.getY());
+ loc.setLocation(loc.getX() + advance, loc.getY());
return loc;
}
@@ -422,7 +416,7 @@ public class PSTextPainter implements TextPainter {
fStyle |= java.awt.Font.ITALIC;
}
return new java.awt.Font(font.getFontName(), fStyle,
- (int)(font.getFontSize() / 1000));
+ (font.getFontSize() / 1000));
}
private float getStringWidth(String str, Font font) {
diff --git a/src/java/org/apache/fop/svg/AbstractFOPBridgeContext.java b/src/java/org/apache/fop/svg/AbstractFOPBridgeContext.java
new file mode 100644
index 000000000..be1c3c122
--- /dev/null
+++ b/src/java/org/apache/fop/svg/AbstractFOPBridgeContext.java
@@ -0,0 +1,139 @@
+/*
+ * 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.svg;
+
+import java.awt.geom.AffineTransform;
+import java.lang.reflect.Constructor;
+
+import org.apache.batik.bridge.Bridge;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.UserAgent;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+
+public abstract class AbstractFOPBridgeContext extends BridgeContext {
+
+ /** The font list. */
+ protected final FontInfo fontInfo;
+
+ protected final ImageManager imageManager;
+ protected final ImageSessionContext imageSessionContext;
+
+ protected final AffineTransform linkTransform;
+
+ /**
+ * Constructs a new bridge context.
+ * @param userAgent the user agent
+ * @param loader the Document Loader to use for referenced documents.
+ * @param fontInfo the font list for the text painter, may be null
+ * in which case text is painted as shapes
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ */
+ public AbstractFOPBridgeContext(UserAgent userAgent,
+ DocumentLoader loader,
+ FontInfo fontInfo,
+ ImageManager imageManager,
+ ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform) {
+ super(userAgent, loader);
+ this.fontInfo = fontInfo;
+ this.imageManager = imageManager;
+ this.imageSessionContext = imageSessionContext;
+ this.linkTransform = linkTransform;
+ }
+
+ /**
+ * Constructs a new bridge context.
+ * @param userAgent the user agent
+ * @param fontInfo the font list for the text painter, may be null
+ * in which case text is painted as shapes
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
+ */
+ public AbstractFOPBridgeContext(UserAgent userAgent,
+ FontInfo fontInfo,
+ ImageManager imageManager,
+ ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform) {
+ super(userAgent);
+ this.fontInfo = fontInfo;
+ this.imageManager = imageManager;
+ this.imageSessionContext = imageSessionContext;
+ this.linkTransform = linkTransform;
+ }
+
+ /**
+ * Constructs a new bridge context.
+ * @param userAgent the user agent
+ * @param fontInfo the font list for the text painter, may be null
+ * in which case text is painted as shapes
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ */
+ public AbstractFOPBridgeContext(UserAgent userAgent,
+ FontInfo fontInfo,
+ ImageManager imageManager,
+ ImageSessionContext imageSessionContext) {
+ this(userAgent, fontInfo, imageManager, imageSessionContext, null);
+ }
+
+ /**
+ * Returns the ImageManager to be used by the ImageElementBridge.
+ * @return the image manager
+ */
+ public ImageManager getImageManager() {
+ return this.imageManager;
+ }
+
+ /**
+ * Returns the ImageSessionContext to be used by the ImageElementBridge.
+ * @return the image session context
+ */
+ public ImageSessionContext getImageSessionContext() {
+ return this.imageSessionContext;
+ }
+
+ protected void putElementBridgeConditional(String className, String testFor) {
+ try {
+ Class.forName(testFor);
+ //if we get here the test class is available
+
+ Class clazz = Class.forName(className);
+ Constructor constructor = clazz.getConstructor(new Class[] {FontInfo.class});
+ putBridge((Bridge)constructor.newInstance(new Object[] {fontInfo}));
+ } catch (Throwable t) {
+ //simply ignore (bridges instantiated over this method are optional)
+ }
+ }
+
+ // Make sure any 'sub bridge contexts' also have our bridges.
+ //TODO There's no matching method in the super-class here
+ public abstract BridgeContext createBridgeContext();
+
+}
diff --git a/src/java/org/apache/fop/svg/AbstractFOPImageElementBridge.java b/src/java/org/apache/fop/svg/AbstractFOPImageElementBridge.java
new file mode 100644
index 000000000..31895cebe
--- /dev/null
+++ b/src/java/org/apache/fop/svg/AbstractFOPImageElementBridge.java
@@ -0,0 +1,284 @@
+/*
+ * 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.svg;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.SVGImageElementBridge;
+import org.apache.batik.gvt.AbstractGraphicsNode;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.util.ParsedURL;
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
+import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
+import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+import org.w3c.dom.Element;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * Bridge class for the &lt;image> element when jpeg images.
+ *
+ * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
+ */
+public abstract class AbstractFOPImageElementBridge extends SVGImageElementBridge {
+
+ /**
+ * Constructs a new bridge for the &lt;image> element.
+ */
+ public AbstractFOPImageElementBridge() { }
+
+ /**
+ * Create the raster image node.
+ * THis checks if it is a jpeg file and creates a jpeg node
+ * so the jpeg can be inserted directly into the pdf document.
+ * @param ctx the bridge context
+ * @param imageElement the svg element for the image
+ * @param purl the parsed url for the image resource
+ * @return a new graphics node
+ */
+ protected GraphicsNode createImageGraphicsNode
+ (BridgeContext ctx, Element imageElement, ParsedURL purl) {
+ AbstractFOPBridgeContext bridgeCtx = (AbstractFOPBridgeContext)ctx;
+
+ ImageManager manager = bridgeCtx.getImageManager();
+ ImageSessionContext sessionContext = bridgeCtx.getImageSessionContext();
+ try {
+ ImageInfo info = manager.getImageInfo(purl.toString(), sessionContext);
+ ImageFlavor[] supportedFlavors = getSupportedFlavours();
+ Image image = manager.getImage(info, supportedFlavors, sessionContext);
+
+ //TODO color profile overrides aren't handled, yet!
+ //ICCColorSpaceExt colorspaceOverride = extractColorSpace(e, ctx);
+ AbstractGraphicsNode specializedNode = null;
+ if (image instanceof ImageXMLDOM) {
+ ImageXMLDOM xmlImage = (ImageXMLDOM)image;
+ if (xmlImage.getDocument() instanceof SVGDocument) {
+ return createSVGImageNode(ctx, imageElement,
+ (SVGDocument)xmlImage.getDocument());
+ } else {
+ //Convert image to Graphics2D
+ image = manager.convertImage(xmlImage,
+ new ImageFlavor[] {ImageFlavor.GRAPHICS2D});
+ }
+ }
+ if (image instanceof ImageRawJPEG) {
+ specializedNode = createLoaderImageNode(image, ctx, imageElement, purl);
+ } else if (image instanceof ImageRawCCITTFax) {
+ specializedNode = createLoaderImageNode(image, ctx, imageElement, purl);
+ } else if (image instanceof ImageGraphics2D) {
+ ImageGraphics2D g2dImage = (ImageGraphics2D)image;
+ specializedNode = new Graphics2DNode(g2dImage);
+ } else {
+ ctx.getUserAgent().displayError(
+ new ImageException("Cannot convert an image to a usable format: " + purl));
+ }
+
+ Rectangle2D imgBounds = getImageBounds(ctx, imageElement);
+ Rectangle2D bounds = specializedNode.getPrimitiveBounds();
+ float [] vb = new float[4];
+ vb[0] = 0; // x
+ vb[1] = 0; // y
+ vb[2] = (float) bounds.getWidth(); // width
+ vb[3] = (float) bounds.getHeight(); // height
+
+ // handles the 'preserveAspectRatio', 'overflow' and 'clip'
+ // and sets the appropriate AffineTransform to the image node
+ initializeViewport(ctx, imageElement, specializedNode, vb, imgBounds);
+ return specializedNode;
+ } catch (Exception e) {
+ ctx.getUserAgent().displayError(e);
+ }
+
+ return superCreateGraphicsNode(ctx, imageElement, purl);
+ }
+
+ /**
+ * Calls the superclass' createImageGraphicNode() method to create the normal GraphicsNode.
+ * @param ctx the bridge context
+ * @param imageElement the image element
+ * @param purl the parsed URL
+ * @return the newly created graphics node
+ * @see org.apache.batik.bridge.SVGImageElementBridge#createGraphicsNode(BridgeContext, Element)
+ */
+ protected GraphicsNode superCreateGraphicsNode
+ (BridgeContext ctx, Element imageElement, ParsedURL purl) {
+ return super.createImageGraphicsNode(ctx, imageElement, purl);
+ }
+
+ /**
+ * Returns an array of supported image flavours
+ *
+ * @return an array of supported image flavours
+ */
+ protected abstract ImageFlavor[] getSupportedFlavours();
+
+ /**
+ * Creates a loader image node implementation
+ * @param purl the parsed url
+ * @param imageElement the image element
+ * @param ctx the batik bridge context
+ * @param image the image
+ *
+ * @return a loader image node implementation
+ */
+ protected LoaderImageNode createLoaderImageNode(
+ Image image, BridgeContext ctx, Element imageElement, ParsedURL purl) {
+ return new LoaderImageNode(image, ctx, imageElement, purl);
+ }
+
+ /**
+ * An image node for natively handled Image instance.
+ * This holds a natively handled image so that it can be drawn into
+ * the PDFGraphics2D.
+ */
+ public class LoaderImageNode extends AbstractGraphicsNode {
+
+ protected final Image image;
+ protected final BridgeContext ctx;
+ protected final Element imageElement;
+ protected final ParsedURL purl;
+ protected GraphicsNode origGraphicsNode = null;
+
+ /**
+ * Create a new image node for drawing natively handled images
+ * into PDF graphics.
+ * @param image the JPEG image
+ * @param ctx the bridge context
+ * @param imageElement the SVG image element
+ * @param purl the URL to the image
+ */
+ public LoaderImageNode(Image image, BridgeContext ctx,
+ Element imageElement, ParsedURL purl) {
+ this.image = image;
+ this.ctx = ctx;
+ this.imageElement = imageElement;
+ this.purl = purl;
+ }
+
+ /** {@inheritDoc} */
+ public Shape getOutline() {
+ return getPrimitiveBounds();
+ }
+
+ /** {@inheritDoc} */
+ public void primitivePaint(Graphics2D g2d) {
+ if (g2d instanceof NativeImageHandler) {
+ NativeImageHandler nativeImageHandler = (NativeImageHandler) g2d;
+ float x = 0;
+ float y = 0;
+ try {
+ float width = image.getSize().getWidthPx();
+ float height = image.getSize().getHeightPx();
+ nativeImageHandler.addNativeImage(image, x, y, width, height);
+ } catch (Exception e) {
+ ctx.getUserAgent().displayError(e);
+ }
+ } else {
+ // Not going directly into PDF so use
+ // original implementation so filters etc work.
+ if (origGraphicsNode == null) {
+ // Haven't constructed base class Graphics Node,
+ // so do so now.
+ origGraphicsNode
+ = superCreateGraphicsNode(ctx, imageElement, purl);
+ }
+ origGraphicsNode.primitivePaint(g2d);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getGeometryBounds() {
+ return getPrimitiveBounds();
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getPrimitiveBounds() {
+ return new Rectangle2D.Double(0, 0,
+ image.getSize().getWidthPx(),
+ image.getSize().getHeightPx());
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getSensitiveBounds() {
+ //No interactive features, just return primitive bounds
+ return getPrimitiveBounds();
+ }
+
+ }
+
+ /**
+ * A node that holds a Graphics2D image.
+ */
+ public class Graphics2DNode extends AbstractGraphicsNode {
+
+ private final ImageGraphics2D image;
+
+ /**
+ * Create a new Graphics2D node.
+ * @param g2d the Graphics2D image
+ */
+ public Graphics2DNode(ImageGraphics2D g2d) {
+ this.image = g2d;
+ }
+
+ /** {@inheritDoc} */
+ public Shape getOutline() {
+ return getPrimitiveBounds();
+ }
+
+ /** {@inheritDoc} */
+ public void primitivePaint(Graphics2D g2d) {
+ int width = image.getSize().getWidthPx();
+ int height = image.getSize().getHeightPx();
+ Rectangle2D area = new Rectangle2D.Double(0, 0, width, height);
+ Graphics2DImagePainter painter = image.getGraphics2DImagePainter();
+ painter.paint(g2d, area);
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getGeometryBounds() {
+ return getPrimitiveBounds();
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getPrimitiveBounds() {
+ return new Rectangle2D.Double(0, 0,
+ image.getSize().getWidthPx(),
+ image.getSize().getHeightPx());
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle2D getSensitiveBounds() {
+ //No interactive features, just return primitive bounds
+ return getPrimitiveBounds();
+ }
+
+ }
+}
diff --git a/src/java/org/apache/fop/afp/AFPTextElementBridge.java b/src/java/org/apache/fop/svg/AbstractFOPTextElementBridge.java
index 2bfccf47d..53b8e2ad5 100644
--- a/src/java/org/apache/fop/afp/AFPTextElementBridge.java
+++ b/src/java/org/apache/fop/svg/AbstractFOPTextElementBridge.java
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,10 +17,10 @@
/* $Id$ */
-package org.apache.fop.afp;
+package org.apache.fop.svg;
-import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.TextPainter;
@@ -31,21 +31,26 @@ import org.w3c.dom.Node;
* Bridge class for the &lt;text> element.
* This bridge will use the direct text painter if the text
* for the element is simple.
+ *
+ * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
-public class AFPTextElementBridge extends SVGTextElementBridge {
-
- private AFPTextPainter textPainter;
+public abstract class AbstractFOPTextElementBridge extends SVGTextElementBridge {
+
+ /** text painter */
+ protected TextPainter textPainter;
/**
- * Constructs a new bridge for the &lt;text> element.
- * @param textPainter the text painter to use
+ * Main constructor
+ *
+ * @param textPainter the text painter
*/
- public AFPTextElementBridge(AFPTextPainter textPainter) {
+ public AbstractFOPTextElementBridge(TextPainter textPainter) {
this.textPainter = textPainter;
}
/**
* Create a text element bridge.
+ *
* This set the text painter on the node if the text is simple.
* @param ctx the bridge context
* @param e the svg element
@@ -53,16 +58,13 @@ public class AFPTextElementBridge extends SVGTextElementBridge {
*/
public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
GraphicsNode node = super.createGraphicsNode(ctx, e);
- if (node != null && isSimple(ctx, e, node)) {
- ((TextNode)node).setTextPainter(getTextPainter());
+ if (node != null) {
+ //Set our own text painter
+ ((TextNode)node).setTextPainter(textPainter);
}
return node;
}
- private TextPainter getTextPainter() {
- return this.textPainter;
- }
-
/**
* Check if text element contains simple text.
* This checks the children of the text element to determine
@@ -75,9 +77,9 @@ public class AFPTextElementBridge extends SVGTextElementBridge {
* @param element the svg text element
* @param node the graphics node
* @return true if this text is simple of false if it cannot be
- * easily rendered using normal drawString on the PDFGraphics2D
+ * easily rendered using normal drawString on the Graphics2D
*/
- private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) {
+ protected boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) {
for (Node n = element.getFirstChild();
n != null;
n = n.getNextSibling()) {
@@ -106,5 +108,6 @@ public class AFPTextElementBridge extends SVGTextElementBridge {
return true;
}
+
}
diff --git a/src/java/org/apache/fop/svg/NativeImageHandler.java b/src/java/org/apache/fop/svg/NativeImageHandler.java
new file mode 100644
index 000000000..8e74cba1d
--- /dev/null
+++ b/src/java/org/apache/fop/svg/NativeImageHandler.java
@@ -0,0 +1,40 @@
+/*
+ * 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.svg;
+
+public interface NativeImageHandler {
+
+ /**
+ * Add a natively handled image directly to the document.
+ * This is used by the ImageElementBridge to draw a natively handled image
+ * (like JPEG or CCITT images)
+ * directly into the document rather than converting the image into
+ * a bitmap and increasing the size.
+ *
+ * @param image the image to draw
+ * @param x the x position
+ * @param y the y position
+ * @param width the width to draw the image
+ * @param height the height to draw the image
+ */
+ void addNativeImage(org.apache.xmlgraphics.image.loader.Image image, float x, float y,
+ float width, float height);
+
+}
diff --git a/src/java/org/apache/fop/svg/PDFBridgeContext.java b/src/java/org/apache/fop/svg/PDFBridgeContext.java
index 6aa29cfa1..364c7a6f3 100644
--- a/src/java/org/apache/fop/svg/PDFBridgeContext.java
+++ b/src/java/org/apache/fop/svg/PDFBridgeContext.java
@@ -20,30 +20,20 @@
package org.apache.fop.svg;
import java.awt.geom.AffineTransform;
-import java.lang.reflect.Constructor;
-import org.apache.batik.bridge.Bridge;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.bridge.UserAgent;
+import org.apache.batik.gvt.TextPainter;
import org.apache.fop.fonts.FontInfo;
-
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-
/**
* BridgeContext which registers the custom bridges for PDF output.
*/
-public class PDFBridgeContext extends BridgeContext {
-
- /** The font list. */
- private final FontInfo fontInfo;
-
- private final ImageManager imageManager;
- private final ImageSessionContext imageSessionContext;
-
- private AffineTransform linkTransform;
+public class PDFBridgeContext extends AbstractFOPBridgeContext {
/**
* Constructs a new bridge context.
@@ -53,18 +43,16 @@ public class PDFBridgeContext extends BridgeContext {
* in which case text is painted as shapes
* @param linkTransform AffineTransform to properly place links,
* may be null
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
*/
- public PDFBridgeContext(UserAgent userAgent,
- DocumentLoader loader,
- FontInfo fontInfo,
- ImageManager imageManager,
- ImageSessionContext imageSessionContext,
- AffineTransform linkTransform) {
- super(userAgent, loader);
- this.fontInfo = fontInfo;
- this.imageManager = imageManager;
- this.imageSessionContext = imageSessionContext;
- this.linkTransform = linkTransform;
+ public PDFBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
+ FontInfo fontInfo, ImageManager imageManager,
+ ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform) {
+ super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
}
/**
@@ -72,19 +60,12 @@ public class PDFBridgeContext extends BridgeContext {
* @param userAgent the user agent
* @param fontInfo the font list for the text painter, may be null
* in which case text is painted as shapes
- * @param linkTransform AffineTransform to properly place links,
- * may be null
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
*/
- public PDFBridgeContext(UserAgent userAgent,
- FontInfo fontInfo,
- ImageManager imageManager,
- ImageSessionContext imageSessionContext,
- AffineTransform linkTransform) {
- super(userAgent);
- this.fontInfo = fontInfo;
- this.imageManager = imageManager;
- this.imageSessionContext = imageSessionContext;
- this.linkTransform = linkTransform;
+ public PDFBridgeContext(UserAgent userAgent, FontInfo fontInfo,
+ ImageManager imageManager, ImageSessionContext imageSessionContext) {
+ super(userAgent, fontInfo, imageManager, imageSessionContext);
}
/**
@@ -92,41 +73,15 @@ public class PDFBridgeContext extends BridgeContext {
* @param userAgent the user agent
* @param fontInfo the font list for the text painter, may be null
* in which case text is painted as shapes
+ * @param imageManager an image manager
+ * @param imageSessionContext an image session context
+ * @param linkTransform AffineTransform to properly place links,
+ * may be null
*/
- public PDFBridgeContext(UserAgent userAgent,
- FontInfo fontInfo,
- ImageManager imageManager,
- ImageSessionContext imageSessionContext) {
- this(userAgent, fontInfo, imageManager, imageSessionContext, null);
- }
-
- /**
- * Returns the ImageManager to be used by the ImageElementBridge.
- * @return the image manager
- */
- public ImageManager getImageManager() {
- return this.imageManager;
- }
-
- /**
- * Returns the ImageSessionContext to be used by the ImageElementBridge.
- * @return the image session context
- */
- public ImageSessionContext getImageSessionContext() {
- return this.imageSessionContext;
- }
-
- private void putPDFElementBridgeConditional(String className, String testFor) {
- try {
- Class.forName(testFor);
- //if we get here the test class is available
-
- Class clazz = Class.forName(className);
- Constructor constructor = clazz.getConstructor(new Class[] {FontInfo.class});
- putBridge((Bridge)constructor.newInstance(new Object[] {fontInfo}));
- } catch (Throwable t) {
- //simply ignore (bridges instantiated over this method are optional)
- }
+ public PDFBridgeContext(SVGUserAgent userAgent, FontInfo fontInfo,
+ ImageManager imageManager, ImageSessionContext imageSessionContext,
+ AffineTransform linkTransform) {
+ super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
}
/** {@inheritDoc} */
@@ -134,23 +89,24 @@ public class PDFBridgeContext extends BridgeContext {
super.registerSVGBridges();
if (fontInfo != null) {
- PDFTextElementBridge textElementBridge = new PDFTextElementBridge(fontInfo);
+ TextPainter textPainter = new PDFTextPainter(fontInfo);
+ SVGTextElementBridge textElementBridge = new PDFTextElementBridge(textPainter);
putBridge(textElementBridge);
//Batik flow text extension (may not always be available)
//putBridge(new PDFBatikFlowTextElementBridge(fontInfo);
- putPDFElementBridgeConditional(
+ putElementBridgeConditional(
"org.apache.fop.svg.PDFBatikFlowTextElementBridge",
"org.apache.batik.extension.svg.BatikFlowTextElementBridge");
//SVG 1.2 flow text support
//putBridge(new PDFSVG12TextElementBridge(fontInfo)); //-->Batik 1.7
- putPDFElementBridgeConditional(
+ putElementBridgeConditional(
"org.apache.fop.svg.PDFSVG12TextElementBridge",
"org.apache.batik.bridge.svg12.SVG12TextElementBridge");
//putBridge(new PDFSVGFlowRootElementBridge(fontInfo));
- putPDFElementBridgeConditional(
+ putElementBridgeConditional(
"org.apache.fop.svg.PDFSVGFlowRootElementBridge",
"org.apache.batik.bridge.svg12.SVGFlowRootElementBridge");
}
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index cafb5f4d3..f8a0bd415 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -100,7 +100,7 @@ import org.apache.xmlgraphics.java2d.GraphicContext;
* @version $Id$
* @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D
*/
-public class PDFGraphics2D extends AbstractGraphics2D {
+public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHandler {
private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
@@ -414,7 +414,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
* @param width the width to draw the image
* @param height the height to draw the image
*/
- void addNativeImage(org.apache.xmlgraphics.image.loader.Image image, float x, float y,
+ public void addNativeImage(org.apache.xmlgraphics.image.loader.Image image, float x, float y,
float width, float height) {
preparePainting();
String key = image.getInfo().getOriginalURI();
@@ -521,7 +521,8 @@ public class PDFGraphics2D extends AbstractGraphics2D {
g.clip(new Rectangle(0, 0, imageWidth, imageHeight));
g.setComposite(gc.getComposite());
- if (!g.drawImage(img, 0, 0, imageWidth, imageHeight, observer)) {
+ boolean drawn = g.drawImage(img, 0, 0, imageWidth, imageHeight, observer);
+ if (!drawn) {
return false;
}
g.dispose();
diff --git a/src/java/org/apache/fop/svg/PDFImageElementBridge.java b/src/java/org/apache/fop/svg/PDFImageElementBridge.java
index 7eb89d2b1..1a17aa410 100644
--- a/src/java/org/apache/fop/svg/PDFImageElementBridge.java
+++ b/src/java/org/apache/fop/svg/PDFImageElementBridge.java
@@ -19,36 +19,14 @@
package org.apache.fop.svg;
-import java.awt.Graphics2D;
-import java.awt.Shape;
-import java.awt.geom.Rectangle2D;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.svg.SVGDocument;
-
-import org.apache.batik.bridge.BridgeContext;
-import org.apache.batik.bridge.SVGImageElementBridge;
-import org.apache.batik.gvt.AbstractGraphicsNode;
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.batik.util.ParsedURL;
-
-import org.apache.xmlgraphics.image.loader.Image;
-import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
-import org.apache.xmlgraphics.image.loader.ImageInfo;
-import org.apache.xmlgraphics.image.loader.ImageManager;
-import org.apache.xmlgraphics.image.loader.ImageSessionContext;
-import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
-import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
-import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
/**
- * Bridge class for the &lt;image> element when jpeg images.
+ * PDF Image Element Bridge class for the &lt;image> element when jpeg images.
*
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
-public class PDFImageElementBridge extends SVGImageElementBridge {
+public class PDFImageElementBridge extends AbstractFOPImageElementBridge {
/**
* Constructs a new bridge for the &lt;image> element.
@@ -60,210 +38,9 @@ public class PDFImageElementBridge extends SVGImageElementBridge {
ImageFlavor.RAW_CCITTFAX,
ImageFlavor.GRAPHICS2D,
ImageFlavor.XML_DOM};
- /**
- * Create the raster image node.
- * THis checks if it is a jpeg file and creates a jpeg node
- * so the jpeg can be inserted directly into the pdf document.
- * @param ctx the bridge context
- * @param imageElement the svg element for the image
- * @param purl the parsed url for the image resource
- * @return a new graphics node
- */
- protected GraphicsNode createImageGraphicsNode
- (BridgeContext ctx, Element imageElement, ParsedURL purl) {
- PDFBridgeContext pdfCtx = (PDFBridgeContext)ctx;
-
- ImageManager manager = pdfCtx.getImageManager();
- ImageSessionContext sessionContext = pdfCtx.getImageSessionContext();
- try {
- ImageInfo info = manager.getImageInfo(purl.toString(), sessionContext);
- Image image = manager.getImage(info, supportedFlavors, sessionContext);
-
- //TODO color profile overrides aren't handled, yet!
- //ICCColorSpaceExt colorspaceOverride = extractColorSpace(e, ctx);
- AbstractGraphicsNode specializedNode = null;
- if (image instanceof ImageXMLDOM) {
- ImageXMLDOM xmlImage = (ImageXMLDOM)image;
- if (xmlImage.getDocument() instanceof SVGDocument) {
- return createSVGImageNode(ctx, imageElement,
- (SVGDocument)xmlImage.getDocument());
- } else {
- //Convert image to Graphics2D
- image = manager.convertImage(xmlImage,
- new ImageFlavor[] {ImageFlavor.GRAPHICS2D});
- }
- }
- if (image instanceof ImageRawJPEG) {
- specializedNode = new LoaderImageNode(image, ctx, imageElement, purl);
- } else if (image instanceof ImageRawCCITTFax) {
- specializedNode = new LoaderImageNode(image, ctx, imageElement, purl);
- } else if (image instanceof ImageGraphics2D) {
- ImageGraphics2D g2dImage = (ImageGraphics2D)image;
- specializedNode = new Graphics2DNode(g2dImage);
- } else {
- ctx.getUserAgent().displayError(
- new ImageException("Cannot convert an image to a usable format: " + purl));
- }
-
- Rectangle2D imgBounds = getImageBounds(ctx, imageElement);
- Rectangle2D bounds = specializedNode.getPrimitiveBounds();
- float [] vb = new float[4];
- vb[0] = 0; // x
- vb[1] = 0; // y
- vb[2] = (float) bounds.getWidth(); // width
- vb[3] = (float) bounds.getHeight(); // height
-
- // handles the 'preserveAspectRatio', 'overflow' and 'clip'
- // and sets the appropriate AffineTransform to the image node
- initializeViewport(ctx, imageElement, specializedNode, vb, imgBounds);
- return specializedNode;
- } catch (Exception e) {
- ctx.getUserAgent().displayError(e);
- }
-
- return superCreateGraphicsNode(ctx, imageElement, purl);
- }
-
- /**
- * Calls the superclass' createImageGraphicNode() method to create the normal GraphicsNode.
- * @param ctx the bridge context
- * @param imageElement the image element
- * @param purl the parsed URL
- * @return the newly created graphics node
- * @see org.apache.batik.bridge.SVGImageElementBridge#createGraphicsNode(BridgeContext, Element)
- */
- protected GraphicsNode superCreateGraphicsNode
- (BridgeContext ctx, Element imageElement, ParsedURL purl) {
- return super.createImageGraphicsNode(ctx, imageElement, purl);
- }
-
-
- /**
- * An image node for natively handled Image instance.
- * This holds a natively handled image so that it can be drawn into
- * the PDFGraphics2D.
- */
- public class LoaderImageNode extends AbstractGraphicsNode {
-
- private Image image;
- private BridgeContext ctx;
- private Element imageElement;
- private ParsedURL purl;
- private GraphicsNode origGraphicsNode = null;
-
- /**
- * Create a new image node for drawing natively handled images
- * into PDF graphics.
- * @param image the JPEG image
- * @param ctx the bridge context
- * @param imageElement the SVG image element
- * @param purl the URL to the image
- */
- public LoaderImageNode(Image image, BridgeContext ctx,
- Element imageElement, ParsedURL purl) {
- this.image = image;
- this.ctx = ctx;
- this.imageElement = imageElement;
- this.purl = purl;
- }
-
- /** {@inheritDoc} */
- public Shape getOutline() {
- return getPrimitiveBounds();
- }
-
- /** {@inheritDoc} */
- public void primitivePaint(Graphics2D g2d) {
- if (g2d instanceof PDFGraphics2D) {
- PDFGraphics2D pdfg = (PDFGraphics2D) g2d;
- float x = 0;
- float y = 0;
- try {
- float width = image.getSize().getWidthPx();
- float height = image.getSize().getHeightPx();
- pdfg.addNativeImage(image, x, y, width, height);
- } catch (Exception e) {
- ctx.getUserAgent().displayError(e);
- }
- } else {
- // Not going directly into PDF so use
- // original implementation so filters etc work.
- if (origGraphicsNode == null) {
- // Haven't constructed baseclass Graphics Node,
- // so do so now.
- origGraphicsNode
- = PDFImageElementBridge.this.superCreateGraphicsNode
- (ctx, imageElement, purl);
- }
- origGraphicsNode.primitivePaint(g2d);
- }
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getGeometryBounds() {
- return getPrimitiveBounds();
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getPrimitiveBounds() {
- return new Rectangle2D.Double(0, 0,
- image.getSize().getWidthPx(),
- image.getSize().getHeightPx());
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getSensitiveBounds() {
- //No interactive features, just return primitive bounds
- return getPrimitiveBounds();
- }
-
- }
-
- /**
- * A node that holds a Graphics2D image.
- */
- public class Graphics2DNode extends AbstractGraphicsNode {
-
- private ImageGraphics2D image;
-
- /**
- * Create a new Graphics2D node.
- * @param g2d the Graphics2D image
- */
- public Graphics2DNode(ImageGraphics2D g2d) {
- this.image = g2d;
- }
-
- /** {@inheritDoc} */
- public Shape getOutline() {
- return getPrimitiveBounds();
- }
-
- /** {@inheritDoc} */
- public void primitivePaint(Graphics2D g2d) {
- int width = image.getSize().getWidthPx();
- int height = image.getSize().getHeightPx();
- Rectangle2D area = new Rectangle2D.Double(0, 0, width, height);
- image.getGraphics2DImagePainter().paint(g2d, area);
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getGeometryBounds() {
- return getPrimitiveBounds();
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getPrimitiveBounds() {
- return new Rectangle2D.Double(0, 0,
- image.getSize().getWidthPx(),
- image.getSize().getHeightPx());
- }
-
- /** {@inheritDoc} */
- public Rectangle2D getSensitiveBounds() {
- //No interactive features, just return primitive bounds
- return getPrimitiveBounds();
- }
+ /** {@inheritDoc} */
+ protected ImageFlavor[] getSupportedFlavours() {
+ return supportedFlavors;
}
}
diff --git a/src/java/org/apache/fop/svg/PDFTextElementBridge.java b/src/java/org/apache/fop/svg/PDFTextElementBridge.java
index 4c11aa97e..c983d2b45 100644
--- a/src/java/org/apache/fop/svg/PDFTextElementBridge.java
+++ b/src/java/org/apache/fop/svg/PDFTextElementBridge.java
@@ -19,13 +19,7 @@
package org.apache.fop.svg;
-import org.apache.batik.bridge.BridgeContext;
-import org.apache.batik.bridge.SVGTextElementBridge;
-import org.apache.batik.gvt.GraphicsNode;
-import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.TextPainter;
-import org.apache.fop.fonts.FontInfo;
-import org.w3c.dom.Element;
/**
* Bridge class for the &lt;text> element.
@@ -34,41 +28,15 @@ import org.w3c.dom.Element;
*
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
-public class PDFTextElementBridge extends SVGTextElementBridge {
-
- private PDFTextPainter pdfTextPainter;
+public class PDFTextElementBridge extends AbstractFOPTextElementBridge {
/**
* Constructs a new bridge for the &lt;text> element.
- * @param fi the font information
- */
- public PDFTextElementBridge(FontInfo fi) {
- pdfTextPainter = new PDFTextPainter(fi);
- }
-
- /**
- * Create a text element bridge.
- * This set the text painter on the node if the text is simple.
- * @param ctx the bridge context
- * @param e the svg element
- * @return the text graphics node created by the super class
+ *
+ * @param textPainter the text painter to use
*/
- public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
- GraphicsNode node = super.createGraphicsNode(ctx, e);
- if (node != null) {
- //Set our own text painter
- ((TextNode)node).setTextPainter(getTextPainter());
- }
- return node;
+ public PDFTextElementBridge(TextPainter textPainter) {
+ super(textPainter);
}
-
- /**
- * Returns the TextPainter instance used by this bridge.
- * @return the text painter
- */
- public TextPainter getTextPainter() {
- return pdfTextPainter;
- }
-
}
diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java
index 06fea54cc..8a0feb3a2 100644
--- a/src/java/org/apache/fop/svg/PDFTextPainter.java
+++ b/src/java/org/apache/fop/svg/PDFTextPainter.java
@@ -43,7 +43,6 @@ import org.apache.batik.gvt.renderer.StrokingTextPainter;
import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;
-
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
@@ -63,8 +62,8 @@ public class PDFTextPainter extends StrokingTextPainter {
private static final boolean DEBUG = false;
- private boolean strokeText = false;
- private FontInfo fontInfo;
+ private final boolean strokeText = false;
+ private final FontInfo fontInfo;
/**
* Create a new PDF text painter with the given font information.
@@ -280,7 +279,7 @@ public class PDFTextPainter extends StrokingTextPainter {
Float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE);
String style = ((posture != null) && (posture.floatValue() > 0.0))
- ? "italic" : "normal";
+ ? Font.STYLE_ITALIC : Font.STYLE_NORMAL;
int weight = ((taWeight != null)
&& (taWeight.floatValue() > 1.0)) ? Font.WEIGHT_BOLD
: Font.WEIGHT_NORMAL;