diff options
-rw-r--r-- | src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java | 124 | ||||
-rw-r--r-- | src/java/org/apache/fop/svg/PDFGraphics2D.java | 31 |
2 files changed, 129 insertions, 26 deletions
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java index a94a4eec7..00d1ec5d7 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -46,6 +46,7 @@ import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.io.OutputStream; import java.io.IOException; +import java.io.StringWriter; import java.util.List; /** @@ -61,13 +62,29 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D implements Configurable, Initializable { private PDFPage currentPage; - private PDFStream pdfStream; private int width; private int height; + //for SVG scaling + private float svgWidth; + private float svgHeight; + private List fontList; + /** number of pages generated */ + protected int pagecount; + /** indicates whether a page is currently being generated */ + protected boolean pagePending; + + /** Initial clipping area, used to restore to original setting when a new page is started. */ + protected Shape initialClip; + /** + * Initial transformation matrix, used to restore to original setting when a new page is + * started. + */ + protected AffineTransform initialTransform; + private Log logger; //Avalon component @@ -174,13 +191,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D this.pdfDoc.setFilterMap( PDFFilterList.buildFilterMapFromConfiguration(cfg)); } - - graphicsState = new PDFState(); - - currentFontName = ""; - currentFontSize = 0; - - pdfStream = this.pdfDoc.getFactory().makeStream(PDFFilterList.CONTENT_FILTER, false); } /** @@ -195,15 +205,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D this.width = width; this.height = height; - PDFResources pdfResources = this.pdfDoc.getResources(); - currentPage = this.pdfDoc.getFactory().makePage(pdfResources, - width, height); - resourceContext = currentPage; - pageRef = currentPage.referencePDF(); - currentStream.write("1 0 0 -1 0 " + height + " cm\n"); - graphicsState.setTransform(new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, (double)height)); pdfDoc.outputHeader(stream); - setOutputStream(stream); } @@ -233,8 +235,8 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D * @param h the height of the page */ public void setSVGDimension(float w, float h) { - currentStream.write("" + PDFNumber.doubleOut(width / w) + " 0 0 " - + PDFNumber.doubleOut(height / h) + " 0 0 cm\n"); + this.svgWidth = w; + this.svgHeight = h; } /** @@ -255,6 +257,83 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D currentStream.write("Q\n"); } + public void nextPage() { + closePage(); + } + + + protected void closePage() { + if (!this.pagePending) { + return; //ignore + } + //Finish page + PDFStream pdfStream = this.pdfDoc.getFactory().makeStream(PDFFilterList.CONTENT_FILTER, false); + pdfStream.add(getString()); + currentStream = null; + this.pdfDoc.registerObject(pdfStream); + currentPage.setContents(pdfStream); + PDFAnnotList annots = currentPage.getAnnotations(); + if (annots != null) { + this.pdfDoc.addObject(annots); + } + this.pdfDoc.addObject(currentPage); + this.currentPage = null; + + this.pagePending = false; + } + + /** {@inheritDoc} */ + protected void preparePainting() { + if (this.pagePending) { + return; + } + try { + startPage(); + } catch (IOException ioe) { + handleIOException(ioe); + } + } + + protected void startPage() throws IOException { + if (this.pagePending) { + throw new IllegalStateException("Close page first before starting another"); + } + //Start page + graphicsState = new PDFState(); + if (this.initialTransform == null) { + //Save initial transformation matrix + this.initialTransform = getTransform(); + this.initialClip = getClip(); + } else { + //Reset transformation matrix + setTransform(this.initialTransform); + setClip(this.initialClip); + } + + currentFontName = ""; + currentFontSize = 0; + + if (currentStream == null) { + currentStream = new StringWriter(); + } + + PDFResources pdfResources = this.pdfDoc.getResources(); + currentPage = this.pdfDoc.getFactory().makePage(pdfResources, + width, height); + resourceContext = currentPage; + pageRef = currentPage.referencePDF(); + graphicsState.setTransform(new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, (double)height)); + currentStream.write("1 0 0 -1 0 " + height + " cm\n"); + if (svgWidth != 0) { + currentStream.write("" + PDFNumber.doubleOut(width / svgWidth) + " 0 0 " + + PDFNumber.doubleOut(height / svgHeight) + " 0 0 cm\n"); + } + + this.pagecount++; + this.pagePending = true; + } + + /** * The rendering process has finished. * This should be called after the rendering has completed as there is @@ -266,14 +345,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D public void finish() throws IOException { // restorePDFState(); - pdfStream.add(getString()); - this.pdfDoc.registerObject(pdfStream); - currentPage.setContents(pdfStream); - PDFAnnotList annots = currentPage.getAnnotations(); - if (annots != null) { - this.pdfDoc.addObject(annots); - } - this.pdfDoc.addObject(currentPage); + closePage(); if (fontInfo != null) { pdfDoc.getResources().addFonts(pdfDoc, fontInfo); } diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java index 79b93d48b..0baa19b71 100644 --- a/src/java/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java @@ -214,6 +214,22 @@ public class PDFGraphics2D extends AbstractGraphics2D { } /** + * Central handler for IOExceptions for this class. + * @param ioe IOException to handle + */ + protected void handleIOException(IOException ioe) { + ioe.printStackTrace(); + } + + /** + * This method is used by PDFDocumentGraphics2D to prepare a new page if + * necessary. + */ + protected void preparePainting() { + //nop, used by PDFDocumentGraphics2D + } + + /** * Set the PDF state to use when starting to draw * into the PDF graphics. * @@ -292,6 +308,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @param linkType the type of link, internal or external */ public void addLink(Rectangle2D bounds, AffineTransform trans, String dest, int linkType) { + preparePainting(); AffineTransform at = getTransform(); Shape b = at.createTransformedShape(bounds); b = trans.createTransformedShape(b); @@ -323,6 +340,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { */ public void addJpegImage(JpegImage jpeg, float x, float y, float width, float height) { + preparePainting(); String key = "__AddJPEG_"+jpegCount; jpegCount++; FopPDFImage fopimage = new FopPDFImage(jpeg, key); @@ -383,6 +401,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { + preparePainting(); // System.err.println("drawImage:x, y"); int width = img.getWidth(observer); @@ -436,6 +455,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { + preparePainting(); //System.out.println("drawImage x=" + x + " y=" + y + " width=" + width + " height=" + height + " image=" + img.toString()); // first we look to see if we've already added this image to // the pdf document. If so, we just reuse the reference; @@ -605,6 +625,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @see #setComposite */ public void draw(Shape s) { + preparePainting(); // System.out.println("draw(Shape)"); AffineTransform trans = getTransform(); double[] tranvals = new double[6]; @@ -744,6 +765,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { if (s == null) { return; } + preparePainting(); PathIterator iter = s.getPathIterator(getTransform()); while (!iter.isDone()) { double vals[] = new double[6]; @@ -793,6 +815,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @param fill true if the colour will be used for filling */ protected void applyColor(Color col, boolean fill) { + preparePainting(); Color c = col; if (c.getColorSpace().getType() == ColorSpace.TYPE_RGB) { @@ -834,6 +857,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @param fill true if the paint should be set for filling */ protected void applyPaint(Paint paint, boolean fill) { + preparePainting(); if (paint instanceof LinearGradientPaint) { LinearGradientPaint gp = (LinearGradientPaint)paint; @@ -946,6 +970,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { } private void createPattern(PatternPaint pp, boolean fill) { + preparePainting(); Rectangle2D rect = pp.getPatternRect(); FontInfo fontInfo = new FontInfo(); @@ -1026,6 +1051,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @param stroke the java stroke */ protected void applyStroke(Stroke stroke) { + preparePainting(); if (stroke instanceof BasicStroke) { BasicStroke bs = (BasicStroke)stroke; @@ -1165,6 +1191,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @see #setClip */ public void drawString(String s, float x, float y) { + preparePainting(); // System.out.println("drawString(String)"); Font fontState; @@ -1298,6 +1325,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { private void addKerning(StringWriter buf, Integer ch1, Integer ch2, Map kerning, String startText, String endText) { + preparePainting(); Map kernPair = (Map)kerning.get(ch1); if (kernPair != null) { @@ -1335,6 +1363,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { */ public void drawString(AttributedCharacterIterator iterator, float x, float y) { + preparePainting(); System.err.println("drawString(AttributedCharacterIterator)"); Font fontState = null; @@ -1414,6 +1443,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @see #setClip */ public void fill(Shape s) { + preparePainting(); // System.err.println("fill"); Color c; c = getBackground(); @@ -1509,6 +1539,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { * @param nonzero true if using the non-zero winding rule */ protected void doDrawing(boolean fill, boolean stroke, boolean nonzero) { + preparePainting(); if (fill) { if (stroke) { if (nonzero) { |