aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/documentation/content/xdocs/trunk/configuration.xml3
-rw-r--r--src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler5
-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
73 files changed, 2335 insertions, 1562 deletions
diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml
index 131b89a37..08463b9b9 100644
--- a/src/documentation/content/xdocs/trunk/configuration.xml
+++ b/src/documentation/content/xdocs/trunk/configuration.xml
@@ -383,7 +383,8 @@
<resource-group-file>resources.afp</resource-group-file>
</renderer>]]></source>
<p>
- The default value for the "images mode" setting is "b+w" (black and white). When the setting is "color" a "bits-per-pixel" setting can be provided. When the setting "native" is set to true, images (TIFF, JPEG and Encapsulated Postscript) will be placed in the datastream in their native form using a MO:DCA Object Container.
+ The default value for the images "mode" setting is "b+w" (black and white). When the images "mode" setting is "b+w" a "bits-per-pixel" setting can be provided to aid the grayscale conversion process. With this setting all images referenced in your source document are converted to an IOCA FS45 grayscale bitmap image form.
+ When the setting is "color" all images are converted to an IOCA FS45 color bitmap image form. When "native" setting is "true", all images encountered (TIFF, GIF, JPEG and Encapsulated Postscript etc.) will be embedded directly in the datastream in their native form using a MO:DCA Object Container.
</p>
<p>
The default value for the "renderer-resolution" is 240 dpi.
diff --git a/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler b/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler
new file mode 100644
index 000000000..deab7d259
--- /dev/null
+++ b/src/java/META-INF/services/org.apache.fop.render.afp.AFPImageHandler
@@ -0,0 +1,5 @@
+org.apache.fop.render.afp.AFPImageHandlerRenderedImage
+org.apache.fop.render.afp.AFPImageHandlerRawCCITTFax
+org.apache.fop.render.afp.AFPImageHandlerRawStream
+org.apache.fop.render.afp.AFPImageHandlerGraphics2D
+org.apache.fop.render.afp.AFPImageHandlerXML
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;