aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeiron Liddle <keiron@apache.org>2002-07-01 14:42:43 +0000
committerKeiron Liddle <keiron@apache.org>2002-07-01 14:42:43 +0000
commit85a11ded6d3e7d7e771fa5351cf1c226437b9194 (patch)
tree06ded29d08973195c2f1ce36252c402687c39446
parente36f21d3a9d76f27a1134d8bf4ab5bd66639c938 (diff)
downloadxmlgraphics-fop-85a11ded6d3e7d7e771fa5351cf1c226437b9194.tar.gz
xmlgraphics-fop-85a11ded6d3e7d7e771fa5351cf1c226437b9194.zip
progressively output pdf objects to reduce memory usage
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194943 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/org/apache/fop/pdf/PDFDocument.java50
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java10
-rw-r--r--src/org/apache/fop/render/pdf/PDFXMLHandler.java8
-rw-r--r--src/org/apache/fop/svg/PDFDocumentGraphics2D.java25
-rw-r--r--src/org/apache/fop/svg/PDFGraphics2D.java50
-rw-r--r--src/org/apache/fop/svg/PDFTranscoder.java11
6 files changed, 94 insertions, 60 deletions
diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java
index 072411ecb..da23546fd 100644
--- a/src/org/apache/fop/pdf/PDFDocument.java
+++ b/src/org/apache/fop/pdf/PDFDocument.java
@@ -140,11 +140,6 @@ public class PDFDocument {
*/
protected HashMap fontMap = new HashMap();
- /**
- * the objects themselves
- */
- protected ArrayList pendingLinks = null;
-
protected HashMap filterMap = new HashMap();
/**
@@ -1015,20 +1010,6 @@ public class PDFDocument {
public void addPage(PDFPage page) {
/* add it to the list of objects */
this.objects.add(page);
-
- if(pendingLinks != null) {
- for(Iterator iter = pendingLinks.iterator(); iter.hasNext(); ) {
- PendingLink pl = (PendingLink)iter.next();
- PDFGoTo gt = new PDFGoTo(++this.objectcount,
- page.referencePDF());
- gt.setDestination(pl.dest);
- addTrailerObject(gt);
- PDFInternalLink internalLink =
- new PDFInternalLink(gt.referencePDF());
- pl.link.setAction(internalLink);
- }
- pendingLinks = null;
- }
}
/**
@@ -1096,25 +1077,6 @@ public class PDFDocument {
this.trailerObjects.add(object);
}
- class PendingLink {
- PDFLink link;
- String dest;
- }
-
- public PDFLink makeLinkCurrentPage(Rectangle rect, String dest) {
- PDFLink link = new PDFLink(++this.objectcount, rect);
- this.objects.add(link);
- PendingLink pl = new PendingLink();
- pl.link = link;
- pl.dest = dest;
- if(pendingLinks == null) {
- pendingLinks = new ArrayList();
- }
- pendingLinks.add(pl);
-
- return link;
- }
-
public PDFLink makeLink(Rectangle rect, String page, String dest) {
PDFLink link = new PDFLink(++this.objectcount, rect);
this.objects.add(link);
@@ -1142,7 +1104,7 @@ public class PDFDocument {
*
* @return the stream object created
*/
- public PDFStream makeStream(String type) {
+ public PDFStream makeStream(String type, boolean add) {
/*
* create a PDFStream with the next object number and add it
@@ -1152,10 +1114,18 @@ public class PDFDocument {
PDFStream obj = new PDFStream(++this.objectcount);
obj.addDefaultFilters(filterMap, type);
- this.objects.add(obj);
+ if(add) {
+ this.objects.add(obj);
+ }
return obj;
}
+ /**
+ * add a stream object
+ */
+ public void addStream(PDFStream obj) {
+ this.objects.add(obj);
+ }
/**
* make an annotation list object
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
index 5fb059a83..c287adf43 100644
--- a/src/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -217,7 +217,7 @@ public class PDFRenderer extends PrintRenderer {
(int) Math.round(w / 1000), (int) Math.round(h / 1000));
pageReferences.put(page, currentPage.referencePDF());
}
- currentStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER);
+ currentStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER, false);
currentState = new PDFState();
currentState.setTransform(new AffineTransform(1, 0, 0, -1, 0, (int) Math.round(pageHeight / 1000)));
@@ -231,6 +231,7 @@ public class PDFRenderer extends PrintRenderer {
//currentStream.add("ET\n");
+ this.pdfDoc.addStream(currentStream);
currentPage.setContents(currentStream);
this.pdfDoc.addPage(currentPage);
this.pdfDoc.output(ostream);
@@ -526,6 +527,12 @@ public class PDFRenderer extends PrintRenderer {
+ xobj + " Do\nQ\nBT\n");
}
+ // output new data
+ try {
+ this.pdfDoc.output(ostream);
+ } catch(IOException ioe) {
+
+ }
}
public void renderForeignObject(ForeignObject fo) {
@@ -540,6 +547,7 @@ public class PDFRenderer extends PrintRenderer {
context.setUserAgent(userAgent);
context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc);
+ context.setProperty(PDFXMLHandler.OUTPUT_STREAM, ostream);
context.setProperty(PDFXMLHandler.PDF_STATE, currentState);
context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage);
context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream);
diff --git a/src/org/apache/fop/render/pdf/PDFXMLHandler.java b/src/org/apache/fop/render/pdf/PDFXMLHandler.java
index b0b95898e..cf733b2df 100644
--- a/src/org/apache/fop/render/pdf/PDFXMLHandler.java
+++ b/src/org/apache/fop/render/pdf/PDFXMLHandler.java
@@ -22,8 +22,8 @@ import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
-import java.io.Writer;
import java.io.IOException;
+import java.io.OutputStream;
import org.apache.batik.bridge.*;
import org.apache.batik.swing.svg.*;
@@ -44,6 +44,7 @@ import java.awt.geom.AffineTransform;
*/
public class PDFXMLHandler implements XMLHandler {
public static final String PDF_DOCUMENT = "pdfDoc";
+public static final String OUTPUT_STREAM = "outputStream";
public static final String PDF_STATE = "pdfState";
public static final String PDF_PAGE = "pdfPage";
public static final String PDF_STREAM = "pdfStream";
@@ -73,6 +74,7 @@ public static final String PDF_YPOS = "ypos";
public static PDFInfo getPDFInfo(RendererContext context) {
PDFInfo pdfi = new PDFInfo();
pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT);
+ pdfi.outputStream = (OutputStream)context.getProperty(OUTPUT_STREAM);
pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE);
pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE);
pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM);
@@ -88,6 +90,7 @@ public static final String PDF_YPOS = "ypos";
public static class PDFInfo {
PDFDocument pdfDoc;
+ OutputStream outputStream;
PDFState pdfState;
PDFPage pdfPage;
public PDFStream currentStream;
@@ -164,7 +167,7 @@ public static final String PDF_YPOS = "ypos";
}
PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fs, pdfInfo.pdfDoc,
- pdfInfo.pdfPage, pdfInfo.currentFontName,
+ pdfInfo.pdfPage, pdfInfo.pdfPage.referencePDF(), pdfInfo.currentFontName,
pdfInfo.currentFontSize,
pdfInfo.currentXPosition,
pdfInfo.currentYPosition);
@@ -175,6 +178,7 @@ public static final String PDF_YPOS = "ypos";
transform.translate(xOffset / 1000f, yOffset / 1000f);
pdfInfo.pdfState.setTransform(transform);
graphics.setPDFState(pdfInfo.pdfState);
+ graphics.setOutputStream(pdfInfo.outputStream);
try {
root.paint(graphics);
pdfInfo.currentStream.add(graphics.getString());
diff --git a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java
index 628817b77..03cd602ea 100644
--- a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java
+++ b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java
@@ -25,6 +25,9 @@ import java.io.IOException;
import org.apache.batik.ext.awt.g2d.GraphicContext;
+import org.apache.fop.image.JpegImage;
+import java.awt.image.ImageObserver;
+
/**
* This class is a wrapper for the <tt>PDFGraphics2D</tt> that
* is used to create a full document around the pdf rendering from
@@ -35,8 +38,6 @@ import org.apache.batik.ext.awt.g2d.GraphicContext;
* @see org.apache.fop.svg.PDFGraphics2D
*/
public class PDFDocumentGraphics2D extends PDFGraphics2D {
- OutputStream stream;
-
PDFPage currentPage;
PDFStream pdfStream;
int width;
@@ -70,7 +71,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
standalone = true;
this.pdfDoc = new PDFDocument();
this.pdfDoc.setProducer("FOP SVG Renderer");
- pdfStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER);
graphicsState = new PDFState();
@@ -78,18 +78,24 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
currentFontSize = 0;
currentYPosition = 0;
currentXPosition = 0;
+
+ pdfStream = this.pdfDoc.makeStream(PDFStream.CONTENT_FILTER, false);
}
- void setupDocument(OutputStream stream, int width, int height) {
+ void setupDocument(OutputStream stream, int width, int height) throws IOException {
this.width = width;
this.height = height;
- this.stream = stream;
PDFResources pdfResources = this.pdfDoc.getResources();
currentPage = this.pdfDoc.makePage(pdfResources,
width, height);
resourceContext = currentPage;
+ pageRef = currentPage.referencePDF();
currentStream.write("1 0 0 -1 0 " + height + " cm\n");
+
+ pdfDoc.outputHeader(stream);
+
+ setOutputStream(stream);
}
/**
@@ -105,7 +111,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
* @param height the height of the document
*/
public PDFDocumentGraphics2D(boolean textAsShapes, OutputStream stream,
- int width, int height) {
+ int width, int height) throws IOException {
this(textAsShapes);
setupDocument(stream, width, height);
}
@@ -154,15 +160,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D {
*/
public void finish() throws IOException {
pdfStream.add(getString());
- PDFResources pdfResources = this.pdfDoc.getResources();
+ this.pdfDoc.addStream(pdfStream);
currentPage.setContents(pdfStream);
this.pdfDoc.addPage(currentPage);
if (fontInfo != null) {
FontSetup.addToResources(pdfDoc, pdfDoc.getResources(), fontInfo);
}
- pdfDoc.outputHeader(stream);
- this.pdfDoc.output(stream);
- pdfDoc.outputTrailer(stream);
+ this.pdfDoc.output(outputStream);
+ pdfDoc.outputTrailer(outputStream);
}
/**
diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java
index 35c589f02..37c9c9573 100644
--- a/src/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/org/apache/fop/svg/PDFGraphics2D.java
@@ -59,6 +59,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
*/
protected PDFDocument pdfDoc;
protected PDFResourceContext resourceContext;
+ protected String pageRef;
/**
* the current state of the pdf graphics
@@ -94,6 +95,14 @@ public class PDFGraphics2D extends AbstractGraphics2D {
protected int currentXPosition = 0;
/**
+ * The output stream for the pdf document.
+ * If this is set then it can progressively output
+ * the pdf document objects to reduce memory.
+ * Especially with images.
+ */
+ protected OutputStream outputStream = null;
+
+ /**
* 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
@@ -113,7 +122,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
* existing document.
*/
public PDFGraphics2D(boolean textAsShapes, FontState fs, PDFDocument doc,
- PDFResourceContext page, String font, float size, int xpos, int ypos) {
+ PDFResourceContext page, String pref, String font, float size, int xpos, int ypos) {
super(textAsShapes);
pdfDoc = doc;
resourceContext = page;
@@ -122,6 +131,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
currentYPosition = ypos;
currentXPosition = xpos;
fontState = fs;
+ pageRef = pref;
graphicsState = new PDFState();
}
@@ -133,6 +143,10 @@ public class PDFGraphics2D extends AbstractGraphics2D {
graphicsState = state;
}
+ public void setOutputStream(OutputStream os) {
+ outputStream = os;
+ }
+
public String getString() {
return currentStream.toString();
}
@@ -175,8 +189,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
if(linkType != PDFLink.EXTERNAL) {
String pdfdest = "/FitR " + dest;
- // TODO use page ref instead
- resourceContext.addAnnotation(pdfDoc.makeLinkCurrentPage(rect, pdfdest));
+ resourceContext.addAnnotation(pdfDoc.makeLink(rect, pageRef, pdfdest));
} else {
resourceContext.addAnnotation(pdfDoc.makeLink(rect,
dest, linkType));
@@ -202,6 +215,13 @@ public class PDFGraphics2D extends AbstractGraphics2D {
+ x + " "
+ (y + height) + " cm\n" + "/Im"
+ xObjectNum + " Do\nQ\n");
+
+ if(outputStream != null) {
+ try {
+ this.pdfDoc.output(outputStream);
+ } catch(IOException ioe) {
+ }
+ }
}
/**
@@ -319,6 +339,13 @@ public class PDFGraphics2D extends AbstractGraphics2D {
fopimg.setColorSpace(new PDFColorSpace(PDFColorSpace.DEVICE_GRAY));
PDFXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
ref = xobj.referencePDF();
+
+ if(outputStream != null) {
+ try {
+ this.pdfDoc.output(outputStream);
+ } catch(IOException ioe) {
+ }
+ }
} else {
mask = null;
}
@@ -327,6 +354,13 @@ public class PDFGraphics2D extends AbstractGraphics2D {
fopimg.setTransparent(new PDFColor(255, 255, 255));
imageInfo.xObjectNum = pdfDoc.addImage(resourceContext, fopimg).getXNumber();
imageInfos.put(img, imageInfo);
+
+ if(outputStream != null) {
+ try {
+ this.pdfDoc.output(outputStream);
+ } catch(IOException ioe) {
+ }
+ }
}
// now do any transformation required and add the actual image
@@ -712,11 +746,12 @@ public class PDFGraphics2D extends AbstractGraphics2D {
PDFResources res = pdfDoc.makeResources();
PDFResourceContext context = new PDFResourceContext(0, pdfDoc, res);
PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, fs,
- pdfDoc, context,
+ pdfDoc, context, pageRef,
currentFontName, currentFontSize,
currentYPosition, currentXPosition);
pattGraphic.gc = (GraphicContext)this.gc.clone();
pattGraphic.gc.validateTransformStack();
+ pattGraphic.setOutputStream(outputStream);
GraphicsNode gn = pp.getGraphicsNode();
gn.paint(pattGraphic);
@@ -754,6 +789,13 @@ public class PDFGraphics2D extends AbstractGraphics2D {
currentStream.write(myPat.getColorSpaceOut(fill));
+ if(outputStream != null) {
+ try {
+ this.pdfDoc.output(outputStream);
+ } catch(IOException ioe) {
+ }
+ }
+
}
}
diff --git a/src/org/apache/fop/svg/PDFTranscoder.java b/src/org/apache/fop/svg/PDFTranscoder.java
index 4c4feaa57..3db4eed52 100644
--- a/src/org/apache/fop/svg/PDFTranscoder.java
+++ b/src/org/apache/fop/svg/PDFTranscoder.java
@@ -32,6 +32,8 @@ import java.net.URL;
import java.util.HashSet;
import java.util.Set;
+import java.io.IOException;
+
import org.apache.batik.transcoder.*;
import org.apache.batik.bridge.BridgeContext;
@@ -266,7 +268,11 @@ public class PDFTranscoder extends XMLAbstractTranscoder {
int w = (int)width;
int h = (int)height;
- graphics.setupDocument(output.getOutputStream(), w, h);
+ try {
+ graphics.setupDocument(output.getOutputStream(), w, h);
+ } catch (IOException ex) {
+ throw new TranscoderException(ex);
+ }
graphics.setSVGDimension(docWidth, docHeight);
currentTransform.setTransform(1, 0, 0, -1, 0, height);
/*if (!stroke) {
@@ -283,8 +289,7 @@ public class PDFTranscoder extends XMLAbstractTranscoder {
try {
graphics.finish();
- } catch (Exception ex) {
- ex.printStackTrace();
+ } catch (IOException ex) {
throw new TranscoderException(ex);
}
}