aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java124
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java31
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) {