aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop
diff options
context:
space:
mode:
authorKeiron Liddle <keiron@apache.org>2002-05-22 08:16:19 +0000
committerKeiron Liddle <keiron@apache.org>2002-05-22 08:16:19 +0000
commit4782dff4a3f004c81401572b78689721d857fbad (patch)
tree735bf1fb6f1abd49aab40351ade5f6f2df90b050 /src/org/apache/fop
parent8203356ff58c5eaa53e833d03dc9499f0f3aee19 (diff)
downloadxmlgraphics-fop-4782dff4a3f004c81401572b78689721d857fbad.tar.gz
xmlgraphics-fop-4782dff4a3f004c81401572b78689721d857fbad.zip
patch to prevent the same image being inserted multiple times
into pdf graphics Submitted by: Paul Reavis <preavis@partnersoft.com> git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194834 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache/fop')
-rw-r--r--src/org/apache/fop/svg/PDFGraphics2D.java194
1 files changed, 112 insertions, 82 deletions
diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java
index 2dd96ad34..880c7ce4a 100644
--- a/src/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/org/apache/fop/svg/PDFGraphics2D.java
@@ -91,6 +91,20 @@ public class PDFGraphics2D extends AbstractGraphics2D {
protected int currentXPosition = 0;
/**
+ * A registry of images that have already been drawn. They are mapped to
+ * a structure with the PDF xObjectNum, width and height. This
+ * prevents multiple copies from being stored, which can greatly
+ * reduce the size of a PDF graphic that uses the same image over and over
+ * (e.g. graphic bullets, map icons, etc.).
+ */
+ private HashMap imageInfos = new HashMap();
+ private static class ImageInfo {
+ public int width;
+ public int height;
+ public int xObjectNum;
+ }
+
+ /**
* Create a new PDFGraphics2D with the given pdf document info.
* This is used to create a Graphics object for use inside an already
* existing document.
@@ -218,91 +232,105 @@ public class PDFGraphics2D extends AbstractGraphics2D {
ImageObserver observer) {
// System.err.println("drawImage:x, y");
- final int width = img.getWidth(observer);
- final int height = img.getHeight(observer);
- if (width == -1 || height == -1) {
- return false;
- }
-
- Dimension size = new Dimension(width * 3, height * 3);
- BufferedImage buf = buildBufferedImage(size);
-
- java.awt.Graphics2D g = buf.createGraphics();
- g.setComposite(AlphaComposite.SrcOver);
- g.setBackground(new Color(1, 1, 1, 0));
- g.setPaint(new Color(1, 1, 1, 0));
- g.fillRect(0, 0, width * 3, height * 3);
- g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
-
- if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) {
- return false;
- }
- g.dispose();
-
- final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3];
- final byte[] mask = new byte[buf.getWidth() * buf.getHeight()];
-
- Raster raster = buf.getData();
- DataBuffer bd = raster.getDataBuffer();
-
- int count = 0;
- int maskpos = 0;
- int[] iarray;
- int i, j, val, alpha, add, mult;
- switch (bd.getDataType()) {
- case DataBuffer.TYPE_INT:
- int[][] idata = ((DataBufferInt)bd).getBankData();
- for (i = 0; i < idata.length; i++) {
- iarray = idata[i];
- for (j = 0; j < iarray.length; j++) {
- val = iarray[j];
- alpha = val >>> 24;
- // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF);
- if (alpha != 255) {
- // System.out.println("Alpha: " + alpha);
- // Composite with opaque white...
- add = (255 - alpha);
- mult = (alpha << 16) / 255;
- result[count++] =
- (byte)(add
- + ((((val >> 16) & 0xFF) * mult) >> 16));
- result[count++] =
- (byte)(add
- + ((((val >> 8) & 0xFF) * mult) >> 16));
- result[count++] = (byte)(add
- + ((((val) & 0xFF) * mult)
- >> 16));
- } else {
- result[count++] = (byte)((val >> 16) & 0xFF);
- result[count++] = (byte)((val >> 8) & 0xFF);
- result[count++] = (byte)((val) & 0xFF);
+ // first we look to see if we've already added this image to
+ // the pdf document. If so, we just reuse the reference;
+ // otherwise we have to build a FopImage and add it to the pdf
+ // document
+ ImageInfo imageInfo = (ImageInfo)imageInfos.get(img);
+ if (imageInfo == null) {
+ // OK, have to build and add a PDF image
+ imageInfo = new ImageInfo();
+ imageInfo.width = img.getWidth(observer);
+ imageInfo.height = img.getHeight(observer);
+
+ if (imageInfo.width == -1 || imageInfo.height == -1) {
+ return false;
+ }
+
+ Dimension size = new Dimension(imageInfo.width * 3, imageInfo.height * 3);
+ BufferedImage buf = buildBufferedImage(size);
+
+ java.awt.Graphics2D g = buf.createGraphics();
+ g.setComposite(AlphaComposite.SrcOver);
+ g.setBackground(new Color(1, 1, 1, 0));
+ g.setPaint(new Color(1, 1, 1, 0));
+ g.fillRect(0, 0, imageInfo.width * 3, imageInfo.height * 3);
+ g.clip(new Rectangle(0, 0, buf.getWidth(), buf.getHeight()));
+
+ if (!g.drawImage(img, 0, 0, buf.getWidth(), buf.getHeight(), observer)) {
+ return false;
+ }
+ g.dispose();
+
+ final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3];
+ final byte[] mask = new byte[buf.getWidth() * buf.getHeight()];
+
+ Raster raster = buf.getData();
+ DataBuffer bd = raster.getDataBuffer();
+
+ int count = 0;
+ int maskpos = 0;
+ int[] iarray;
+ int i, j, val, alpha, add, mult;
+ switch (bd.getDataType()) {
+ case DataBuffer.TYPE_INT:
+ int[][] idata = ((DataBufferInt)bd).getBankData();
+ for (i = 0; i < idata.length; i++) {
+ iarray = idata[i];
+ for (j = 0; j < iarray.length; j++) {
+ val = iarray[j];
+ alpha = val >>> 24;
+ // mask[maskpos++] = (byte)((idata[i][j] >> 24) & 0xFF);
+ if (alpha != 255) {
+ // System.out.println("Alpha: " + alpha);
+ // Composite with opaque white...
+ add = (255 - alpha);
+ mult = (alpha << 16) / 255;
+ result[count++] =
+ (byte)(add
+ + ((((val >> 16) & 0xFF) * mult) >> 16));
+ result[count++] =
+ (byte)(add
+ + ((((val >> 8) & 0xFF) * mult) >> 16));
+ result[count++] = (byte)(add
+ + ((((val) & 0xFF) * mult)
+ >> 16));
+ } else {
+ result[count++] = (byte)((val >> 16) & 0xFF);
+ result[count++] = (byte)((val >> 8) & 0xFF);
+ result[count++] = (byte)((val) & 0xFF);
+ }
}
}
+ break;
+ default:
+ // error
+ break;
+ }
+
+ try {
+ FopImage fopimg = new TempImage("TempImage:" + img.toString(), buf.getWidth(), buf.getHeight(), result, mask);
+ imageInfo.xObjectNum = this.pdfDoc.addImage(fopimg);
+ imageInfos.put(img, imageInfo);
+ } catch (Exception e) {
+ e.printStackTrace();
}
- break;
- default:
- // error
- break;
}
- try {
- FopImage fopimg = new TempImage(buf.getWidth(), buf.getHeight(), result, mask);
- int xObjectNum = this.pdfDoc.addImage(fopimg);
- AffineTransform at = getTransform();
- double[] matrix = new double[6];
- at.getMatrix(matrix);
- currentStream.write("q\n");
- Shape imclip = getClip();
- writeClip(imclip);
- currentStream.write("" + matrix[0] + " " + matrix[1] + " "
- + matrix[2] + " " + matrix[3] + " "
- + matrix[4] + " " + matrix[5] + " cm\n");
- currentStream.write("" + width + " 0 0 " + (-height) + " " + x
- + " " + (y + height) + " cm\n" + "/Im"
- + xObjectNum + " Do\nQ\n");
- } catch (Exception e) {
- e.printStackTrace();
- }
+ // now do any transformation required and add the actual image
+ // placement instance
+ AffineTransform at = getTransform();
+ double[] matrix = new double[6];
+ at.getMatrix(matrix);
+ currentStream.write("q\n");
+ Shape imclip = getClip();
+ writeClip(imclip);
+ currentStream.write("" + matrix[0] + " " + matrix[1] + " "
+ + matrix[2] + " " + matrix[3] + " "
+ + matrix[4] + " " + matrix[5] + " cm\n");
+ currentStream.write("" + imageInfo.width + " 0 0 " + (-imageInfo.height) + " " + x
+ + " " + (y + imageInfo.height) + " cm\n" + "/Im"
+ + imageInfo.xObjectNum + " Do\nQ\n");
return true;
}
@@ -320,9 +348,11 @@ public class PDFGraphics2D extends AbstractGraphics2D {
byte[] m_bitmaps;
byte[] m_mask;
PDFColor transparent = new PDFColor(255, 255, 255);
+ String url;
- TempImage(int width, int height, byte[] result,
+ TempImage(String url, int width, int height, byte[] result,
byte[] mask) {
+ this.url = url;
this.m_height = height;
this.m_width = width;
this.m_bitsPerPixel = 8;
@@ -342,7 +372,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
}
public String getURL() {
- return "" + m_bitmaps;
+ return url;
}
// image size