aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2005-10-26 21:07:47 +0000
committerJeremias Maerki <jeremias@apache.org>2005-10-26 21:07:47 +0000
commitef1fd8f1519e90cc86a8d74a38f59d45e153948e (patch)
tree438828acdd98d79f00d3e926549b58bbe24eb024 /src
parent34cfe36db9948152d7b7db4aa2638c215d532999 (diff)
downloadxmlgraphics-fop-ef1fd8f1519e90cc86a8d74a38f59d45e153948e.tar.gz
xmlgraphics-fop-ef1fd8f1519e90cc86a8d74a38f59d45e153948e.zip
Bugzilla #37236:
Fix for gradients and patterns for SVG to PDF transcoding. Improvement for break-out handling in PDF Renderer. Submitted by: Thomas Deweese <deweese.at.apache.org> git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@328731 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java4
-rw-r--r--src/java/org/apache/fop/pdf/PDFState.java44
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java19
-rw-r--r--src/java/org/apache/fop/render/ps/PSGraphics2D.java9
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java13
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java176
6 files changed, 163 insertions, 102 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index bacb3251c..5ef2a72a1 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -688,7 +688,7 @@ public class PDFFactory {
public PDFPattern makeGradient(PDFResourceContext res, boolean radial,
PDFColorSpace theColorspace,
List theColors, List theBounds,
- List theCoords) {
+ List theCoords, List theMatrix) {
PDFShading myShad;
PDFFunction myfunky;
PDFFunction myfunc;
@@ -770,7 +770,7 @@ public class PDFFactory {
}
- myPattern = makePattern(res, 2, myShad, null, null, null);
+ myPattern = makePattern(res, 2, myShad, null, null, theMatrix);
return (myPattern);
}
diff --git a/src/java/org/apache/fop/pdf/PDFState.java b/src/java/org/apache/fop/pdf/PDFState.java
index f2ebe6ea9..15f4527c2 100644
--- a/src/java/org/apache/fop/pdf/PDFState.java
+++ b/src/java/org/apache/fop/pdf/PDFState.java
@@ -68,11 +68,11 @@ public class PDFState {
Data copy;
try {
copy = (Data)getData().clone();
+ getData().resetTransform();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e.getMessage());
}
stateStack.add(copy);
- data.resetConcatenations();
}
/**
@@ -280,16 +280,15 @@ public class PDFState {
* @return the calculate combined transform for the current state
*/
public AffineTransform getTransform() {
- AffineTransform tf;
- AffineTransform at = new AffineTransform();
- for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
- Data d = (Data)iter.next();
- tf = d.transform;
- at.concatenate(tf);
- }
- at.concatenate(getData().transform);
-
- return at;
+ AffineTransform tf;
+ AffineTransform at = new AffineTransform();
+ for (Iterator iter = stateStack.iterator(); iter.hasNext();) {
+ Data d = (Data)iter.next();
+ tf = d.transform;
+ at.concatenate(tf);
+ }
+ at.concatenate(getData().transform);
+ return at;
}
/**
@@ -339,8 +338,6 @@ public class PDFState {
public String fontName = "";
public Shape clip = null;
public PDFGState gstate = null;
- /** Log of all concatenation operations */
- public List concatenations = null;
/** @see java.lang.Object#clone() */
@@ -362,19 +359,20 @@ public class PDFState {
obj.fontName = this.fontName;
obj.clip = this.clip;
obj.gstate = this.gstate;
- if (this.concatenations != null) {
- obj.concatenations = new java.util.ArrayList(this.concatenations);
- }
return obj;
}
/**
- * Forgets the previously made AffineTransform concatenations.
+ * Get the current Transform.
*/
- public void resetConcatenations() {
- this.concatenations = null;
+ public AffineTransform getTransform() {
+ return transform;
}
-
+
+ public void resetTransform() {
+ transform = new AffineTransform();
+ }
+
/**
* Concatenate the given AffineTransform with the current thus creating
* a new viewport. Note that all concatenation operations are logged
@@ -383,16 +381,12 @@ public class PDFState {
* @param at Transformation to perform
*/
public void concatenate(AffineTransform at) {
- if (this.concatenations == null) {
- this.concatenations = new java.util.ArrayList();
- }
- concatenations.add(at);
transform.concatenate(at);
}
/** @see java.lang.Object#toString() */
public String toString() {
- return super.toString() + ", " + this.transform + " | " + this.concatenations;
+ return super.toString() + ", " + this.transform;
}
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 69a96f432..ed129317b 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -928,21 +928,18 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
comment("------ restoring context after break-out...");
PDFState.Data data;
Iterator i = breakOutList.iterator();
+ double[] matrix = new double[6];
while (i.hasNext()) {
data = (PDFState.Data)i.next();
currentState.push();
saveGraphicsState();
- if (data.concatenations != null) {
- Iterator tr = data.concatenations.iterator();
- while (tr.hasNext()) {
- AffineTransform at = (AffineTransform)tr.next();
- currentState.setTransform(at);
- double[] matrix = new double[6];
- at.getMatrix(matrix);
- tempctm = new CTM(matrix[0], matrix[1], matrix[2], matrix[3],
- matrix[4] * 1000, matrix[5] * 1000);
- currentStream.add(CTMHelper.toPDFString(tempctm) + " cm\n");
- }
+ AffineTransform at = data.getTransform();
+ if (!at.isIdentity()) {
+ currentState.setTransform(at);
+ at.getMatrix(matrix);
+ tempctm = new CTM(matrix[0], matrix[1], matrix[2], matrix[3],
+ matrix[4] * 1000, matrix[5] * 1000);
+ currentStream.add(CTMHelper.toPDFString(tempctm) + " cm\n");
}
//TODO Break-out: Also restore items such as line width and color
//Left out for now because all this painting stuff is very
diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2D.java b/src/java/org/apache/fop/render/ps/PSGraphics2D.java
index 4bfea700a..464840031 100644
--- a/src/java/org/apache/fop/render/ps/PSGraphics2D.java
+++ b/src/java/org/apache/fop/render/ps/PSGraphics2D.java
@@ -134,6 +134,15 @@ public class PSGraphics2D extends AbstractGraphics2D {
*/
public PSGraphics2D(PSGraphics2D g) {
super(g);
+
+ setPSGenerator(g.gen);
+ this.clippingDisabled = g.clippingDisabled;
+ this.font = g.font;
+ this.overrideFont = g.overrideFont;
+ this.currentFontName = g.currentFontName;
+ this.currentFontSize = g.currentFontSize;
+ this.currentColour = g.currentColour;
+ this.fontInfo = g.fontInfo;
}
/**
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
index d90857743..85e5f667f 100644
--- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
@@ -305,12 +305,19 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
resourceContext = page;
pdfContext.setCurrentPage(page);
pageRef = page.referencePDF();
- graphicsState.setTransform(new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, (double)height));
+
+ AffineTransform at = 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");
+ double scaleX = width / svgWidth;
+ double scaleY = height / svgHeight;
+ at.scale(scaleX, scaleY);
+ currentStream.write("" + PDFNumber.doubleOut(scaleX) + " 0 0 "
+ + PDFNumber.doubleOut(scaleY) + " 0 0 cm\n");
}
+ // Remember the transform we installed.
+ graphicsState.setTransform(at);
pdfContext.increasePageCount();
}
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index 4d91422d3..b3a49da37 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -279,6 +279,15 @@ public class PDFGraphics2D extends AbstractGraphics2D {
}
/**
+ * Get the string buffer from the currentStream, containing all
+ * the commands written into this Grpahics so far.
+ * @return the StringBuffer containing the PDF markup
+ */
+ public StringBuffer getBuffer() {
+ return currentStream.getBuffer();
+ }
+
+ /**
* Set the Grpahics context.
* @param c the graphics context to use
*/
@@ -829,17 +838,27 @@ public class PDFGraphics2D extends AbstractGraphics2D {
LinearGradientPaint gp = (LinearGradientPaint)paint;
Color[] cols = gp.getColors();
float[] fractions = gp.getFractions();
- Point2D p1 = gp.getStartPoint();
- Point2D p2 = gp.getEndPoint();
+
//MultipleGradientPaint.CycleMethodEnum cycenum = gp.getCycleMethod();
//boolean cyclic = (cycenum == MultipleGradientPaint.REPEAT);
- AffineTransform transform = graphicsState.getTransform();
- transform.concatenate(gp.getTransform());
+ // This code currently doesn't support 'repeat' as PDF has
+ // no way to support this (we need to rasterize).
+
+ // Build proper transform from gradient space to page space
+ // ('Patterns' don't get userspace transform).
+ AffineTransform transform;
+ transform = new AffineTransform(graphicsState.getTransform());
transform.concatenate(getTransform());
+ transform.concatenate(gp.getTransform());
- p1 = transform.transform(p1, null);
- p2 = transform.transform(p2, null);
+ List theMatrix = new java.util.ArrayList();
+ double [] mat = new double[6];
+ transform.getMatrix(mat);
+ for (int idx=0; idx<mat.length; idx++)
+ theMatrix.add(new Double(mat[idx]));
+ Point2D p1 = gp.getStartPoint();
+ Point2D p2 = gp.getEndPoint();
List theCoords = new java.util.ArrayList();
theCoords.add(new Double(p1.getX()));
theCoords.add(new Double(p1.getY()));
@@ -874,46 +893,56 @@ public class PDFGraphics2D extends AbstractGraphics2D {
}
}
- PDFColorSpace aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+ PDFColorSpace aColorSpace;
+ aColorSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
PDFPattern myPat = pdfDoc.getFactory().makeGradient(
resourceContext, false, aColorSpace,
- someColors, theBounds, theCoords);
+ someColors, theBounds, theCoords, theMatrix);
currentStream.write(myPat.getColorSpaceOut(fill));
} else if (paint instanceof RadialGradientPaint) {
RadialGradientPaint rgp = (RadialGradientPaint)paint;
+ AffineTransform transform;
+ transform = new AffineTransform(graphicsState.getTransform());
+ transform.concatenate(getTransform());
+ transform.concatenate(rgp.getTransform());
+
+ List theMatrix = new java.util.ArrayList();
+ double [] mat = new double[6];
+ transform.getMatrix(mat);
+ for (int idx=0; idx<mat.length; idx++)
+ theMatrix.add(new Double(mat[idx]));
+
double ar = rgp.getRadius();
Point2D ac = rgp.getCenterPoint();
Point2D af = rgp.getFocusPoint();
- AffineTransform transform = graphicsState.getTransform();
- AffineTransform gradt = rgp.getTransform();
- transform.concatenate(gradt);
-
- // find largest scaling for the radius
- double scale = gradt.getScaleX();
- if (gradt.getScaleY() > scale) {
- scale = gradt.getScaleY();
- }
- ar = ar * scale;
- ac = transform.transform(ac, null);
- af = transform.transform(af, null);
List theCoords = new java.util.ArrayList();
- // the center point af must be within the circle with
- // radius ar centered at ac
- theCoords.add(new Double(af.getX()));
- theCoords.add(new Double(af.getY()));
+ double dx = af.getX()-ac.getX();
+ double dy = af.getY()-ac.getY();
+ double d = Math.sqrt(dx*dx+dy*dy);
+ if (d > ar) {
+ // the center point af must be within the circle with
+ // radius ar centered at ac so limit it to that.
+ double scale = (ar*.9999)/d;
+ dx = dx*scale;
+ dy = dy*scale;
+ }
+
+ theCoords.add(new Double(ac.getX()+dx)); // Fx
+ theCoords.add(new Double(ac.getY()+dy)); // Fy
theCoords.add(new Double(0));
- theCoords.add(new Double(ac.getX())); // Fx
- theCoords.add(new Double(ac.getY())); // Fy
+ theCoords.add(new Double(ac.getX()));
+ theCoords.add(new Double(ac.getY()));
theCoords.add(new Double(ar));
Color[] cols = rgp.getColors();
List someColors = new java.util.ArrayList();
for (int count = 0; count < cols.length; count++) {
Color cc = cols[count];
- someColors.add(new PDFColor(cc.getRed(), cc.getGreen(), cc.getBlue()));
+ someColors.add(new PDFColor(cc.getRed(), cc.getGreen(),
+ cc.getBlue()));
}
float[] fractions = rgp.getFractions();
@@ -922,10 +951,12 @@ public class PDFGraphics2D extends AbstractGraphics2D {
float offset = fractions[count];
theBounds.add(new Double(offset));
}
- PDFColorSpace colSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
- PDFPattern myPat = pdfDoc.getFactory().makeGradient(
- resourceContext, true, colSpace,
- someColors, theBounds, theCoords);
+ PDFColorSpace colSpace;
+ colSpace = new PDFColorSpace(PDFColorSpace.DEVICE_RGB);
+
+ PDFPattern myPat = pdfDoc.getFactory().makeGradient
+ (resourceContext, true, colSpace,
+ someColors, theBounds, theCoords, theMatrix);
currentStream.write(myPat.getColorSpaceOut(fill));
@@ -937,7 +968,6 @@ public class PDFGraphics2D extends AbstractGraphics2D {
private void createPattern(PatternPaint pp, boolean fill) {
preparePainting();
- Rectangle2D rect = pp.getPatternRect();
FontInfo fontInfo = new FontInfo();
FontSetup.setup(fontInfo, null);
@@ -947,41 +977,64 @@ public class PDFGraphics2D extends AbstractGraphics2D {
PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, fontInfo,
pdfDoc, context, pageRef,
"", 0);
- pattGraphic.gc = (GraphicContext)this.gc.clone();
+ pattGraphic.setGraphicContext(new GraphicContext());
pattGraphic.gc.validateTransformStack();
+ pattGraphic.setRenderingHints(this.getRenderingHints());
pattGraphic.setOutputStream(outputStream);
GraphicsNode gn = pp.getGraphicsNode();
- gn.paint(pattGraphic);
-
- StringWriter pattStream = new StringWriter();
- pattStream.write("q\n");
-
- // this makes the pattern the right way up, since
- // it is outside the original transform around the
- // whole svg document
- pattStream.write("1 0 0 -1 0 " + (rect.getHeight() + rect.getY()) + " cm\n");
+ Rectangle2D gnBBox = gn.getBounds();
+ Rectangle2D rect = pp.getPatternRect();
- pattStream.write(pattGraphic.getString());
- pattStream.write("Q");
+ // if (!pp.getOverflow()) {
+ gn.paint(pattGraphic);
+ // } else {
+ // /* Commented out until SVN version of Batik is included */
+ // // For overflow we need to paint the content from
+ // // all the tiles who's overflow will intersect one
+ // // tile (left->right, top->bottom). Then we can
+ // // simply replicate that tile as normal.
+ // double gnMinX = gnBBox.getX();
+ // double gnMaxX = gnBBox.getX() + gnBBox.getWidth();
+ // double gnMinY = gnBBox.getY();
+ // double gnMaxY = gnBBox.getY() + gnBBox.getHeight();
+ // double patMaxX = rect.getX() + rect.getWidth();
+ // double patMaxY = rect.getY() + rect.getHeight();
+ // double stepX = rect.getWidth();
+ // double stepY = rect.getHeight();
+ //
+ // int startX = (int)((rect.getX() - gnMaxX)/stepX);
+ // int startY = (int)((rect.getY() - gnMaxY)/stepY);
+ //
+ // int endX = (int)((patMaxX - gnMinX)/stepX);
+ // int endY = (int)((patMaxY - gnMinY)/stepY);
+ //
+ // pattGraphic.translate(startX*stepX, startY*stepY);
+ // for (int yIdx=startY; yIdx<=endY; yIdx++) {
+ // for (int xIdx=startX; xIdx<=endX; xIdx++) {
+ // gn.paint(pattGraphic);
+ // pattGraphic.translate(stepX,0);
+ // }
+ // pattGraphic.translate(-(endX-startX+1)*stepX, stepY);
+ // }
+ // }
List bbox = new java.util.ArrayList();
- bbox.add(new Double(0));
- bbox.add(new Double(0));
- bbox.add(new Double(rect.getWidth() + rect.getX()));
- bbox.add(new Double(rect.getHeight() + rect.getY()));
-
- List translate = new java.util.ArrayList();
- AffineTransform pattt = pp.getPatternTransform();
- pattt.translate(rect.getWidth() + rect.getX(), rect.getHeight() + rect.getY());
- double[] flatmatrix = new double[6];
- pattt.getMatrix(flatmatrix);
- translate.add(new Double(flatmatrix[0]));
- translate.add(new Double(flatmatrix[1]));
- translate.add(new Double(flatmatrix[2]));
- translate.add(new Double(flatmatrix[3]));
- translate.add(new Double(flatmatrix[4]));
- translate.add(new Double(flatmatrix[5]));
+ bbox.add(new Double(rect.getX()));
+ bbox.add(new Double(rect.getHeight()+rect.getY()));
+ bbox.add(new Double(rect.getWidth() +rect.getX()));
+ bbox.add(new Double(rect.getY()));
+
+ AffineTransform transform;
+ transform = new AffineTransform(graphicsState.getTransform());
+ transform.concatenate(getTransform());
+ transform.concatenate(pp.getPatternTransform());
+
+ List theMatrix = new java.util.ArrayList();
+ double [] mat = new double[6];
+ transform.getMatrix(mat);
+ for (int idx=0; idx<mat.length; idx++)
+ theMatrix.add(new Double(mat[idx]));
/** @todo see if pdfDoc and res can be linked here,
(currently res <> PDFDocument's resources) so addFonts()
@@ -991,7 +1044,8 @@ public class PDFGraphics2D extends AbstractGraphics2D {
PDFPattern myPat = pdfDoc.getFactory().makePattern(
resourceContext, 1, res, 1, 1, bbox,
rect.getWidth(), rect.getHeight(),
- translate, null, pattStream.getBuffer());
+ theMatrix, null,
+ pattGraphic.getBuffer());
currentStream.write(myPat.getColorSpaceOut(fill));