diff options
author | Keiron Liddle <keiron@apache.org> | 2002-07-01 14:42:43 +0000 |
---|---|---|
committer | Keiron Liddle <keiron@apache.org> | 2002-07-01 14:42:43 +0000 |
commit | 85a11ded6d3e7d7e771fa5351cf1c226437b9194 (patch) | |
tree | 06ded29d08973195c2f1ce36252c402687c39446 | |
parent | e36f21d3a9d76f27a1134d8bf4ab5bd66639c938 (diff) | |
download | xmlgraphics-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.java | 50 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/PDFRenderer.java | 10 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/PDFXMLHandler.java | 8 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFDocumentGraphics2D.java | 25 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFGraphics2D.java | 50 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFTranscoder.java | 11 |
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); } } |