Bläddra i källkod

My last attempt at fixing SVG gradients in PDF wasn't successful. This one is:

Improved resolution of transformation matrices in PDF patterns.
Renamed PDFState.setTransform() to PDFState.concatenate() because setTransform() does a concationation and is therefore misleading. The old method is still there (just in case) but it is deprecated.
Simplified the whole transformation tracking by including the basic page transformation in the stack.
Verified the changes with basic-links in FO, fixed block-containers, a-links in SVG and SVG gradients.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@437210 13f79535-47bb-0310-9956-ffa450edef68
pull/25/head
Jeremias Maerki 18 år sedan
förälder
incheckning
9ca50a2705

+ 4
- 2
src/java/org/apache/fop/pdf/PDFPattern.java Visa fil

@@ -250,7 +250,8 @@ public class PDFPattern extends PDFPathPaint {
vectorSize = this.matrix.size();
p.append("/Matrix [ ");
for (tempInt = 0; tempInt < vectorSize; tempInt++) {
p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt)));
p.append(PDFNumber.doubleOut(
((Double)this.matrix.get(tempInt)).doubleValue(), 8));
p.append(" ");
}
p.append("] \n");
@@ -303,7 +304,8 @@ public class PDFPattern extends PDFPathPaint {
vectorSize = this.matrix.size();
p.append("/Matrix [ ");
for (tempInt = 0; tempInt < vectorSize; tempInt++) {
p.append(PDFNumber.doubleOut((Double)this.matrix.get(tempInt)));
p.append(PDFNumber.doubleOut(
((Double)this.matrix.get(tempInt)).doubleValue(), 8));
p.append(" ");
}
p.append("] \n");

+ 9
- 0
src/java/org/apache/fop/pdf/PDFState.java Visa fil

@@ -267,8 +267,17 @@ public class PDFState {
* the current graphic state.
*
* @param tf the transform to concatonate to the current level transform
* @deprecated This method name is misleading. Use concatenate(AffineTransform) instead!
*/
public void setTransform(AffineTransform tf) {
concatenate(tf);
}
/**
* Concatenates the given AffineTransform to the current one.
* @param tf the transform to concatenate to the current level transform
*/
public void concatenate(AffineTransform tf) {
getData().concatenate(tf);
}


+ 1
- 1
src/java/org/apache/fop/render/pdf/PDFGraphics2DAdapter.java Visa fil

@@ -94,7 +94,7 @@ public class PDFGraphics2DAdapter extends AbstractGraphics2DAdapter {
AffineTransform transform = new AffineTransform();
transform.translate(fx, fy);
pdfInfo.pdfState.setTransform(transform);
pdfInfo.pdfState.concatenate(transform);
graphics.setPDFState(pdfInfo.pdfState);
graphics.setOutputStream(pdfInfo.outputStream);

+ 6
- 15
src/java/org/apache/fop/render/pdf/PDFRenderer.java Visa fil

@@ -208,9 +208,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
/** Optional URI to an output profile to be used. */
protected String outputProfileURI;
/** The current Transform */
protected AffineTransform currentBasicTransform;

/** drawing state */
protected PDFState currentState = null;

@@ -704,16 +701,11 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
.makeStream(PDFFilterList.CONTENT_FILTER, false);

currentState = new PDFState();
/* This transform shouldn't affect PDFState as it only sets the basic
* coordinate system for the rendering process.
*
currentState.setTransform(new AffineTransform(1, 0, 0, -1, 0,
(int) Math.round(pageHeight / 1000)));
*/
// Transform origin at top left to origin at bottom left
currentBasicTransform = new AffineTransform(1, 0, 0, -1, 0,
// Transform the PDF's default coordinate system (0,0 at lower left) to the PDFRenderer's
AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
pageHeight / 1000f);
currentStream.add(CTMHelper.toPDFString(currentBasicTransform, false) + " cm\n");
currentState.concatenate(basicPageTransform);
currentStream.add(CTMHelper.toPDFString(basicPageTransform, false) + " cm\n");
currentFontName = "";
@@ -736,7 +728,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
protected void startVParea(CTM ctm, Rectangle2D clippingRect) {
// Set the given CTM in the graphics state
currentState.push();
currentState.setTransform(
currentState.concatenate(
new AffineTransform(CTMHelper.toPDFArray(ctm)));

saveGraphicsState();
@@ -1069,7 +1061,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
saveGraphicsState();
AffineTransform at = data.getTransform();
if (!at.isIdentity()) {
currentState.setTransform(at);
currentState.concatenate(at);
at.getMatrix(matrix);
tempctm = new CTM(matrix[0], matrix[1], matrix[2], matrix[3],
matrix[4] * 1000, matrix[5] * 1000);
@@ -1130,7 +1122,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
// transform rect to absolute coords
AffineTransform transform = currentState.getTransform();
rect = transform.createTransformedShape(rect).getBounds2D();
rect = currentBasicTransform.createTransformedShape(rect).getBounds2D();

int type = internal ? PDFLink.INTERNAL : PDFLink.EXTERNAL;
PDFLink pdflink = pdfDoc.getFactory().makeLink(

+ 17
- 22
src/java/org/apache/fop/render/pdf/PDFSVGHandler.java Visa fil

@@ -26,16 +26,12 @@ import java.awt.Color;
import java.awt.geom.AffineTransform;

import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGAElement;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;

import org.apache.fop.render.AbstractGenericSVGHandler;
import org.apache.fop.render.Renderer;
import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContextConstants;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFState;
import org.apache.fop.pdf.PDFStream;
@@ -56,7 +52,6 @@ import org.apache.avalon.framework.configuration.Configuration;

import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.util.SVGConstants;
@@ -173,11 +168,6 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler
AffineTransform resolutionScaling = new AffineTransform();
resolutionScaling.scale(s, s);
//Transformation matrix that establishes the local coordinate system for the SVG graphic
//in relation to PDF's initial coordinate system.
AffineTransform baseTransform = (AffineTransform)renderer.currentBasicTransform.clone();
baseTransform.concatenate(pdfInfo.pdfState.getTransform());

GVTBuilder builder = new GVTBuilder();
//Controls whether text painted by Batik is generated using text or path operations
@@ -211,16 +201,12 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler
AffineTransform scaling = new AffineTransform(
sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f);

//Finish the baseTransform, now that we know everything
baseTransform.concatenate(scaling);
baseTransform.concatenate(resolutionScaling);
//Transformation matrix that establishes the local coordinate system for the SVG graphic
//in relation to the current coordinate system
AffineTransform imageTransform = new AffineTransform();
imageTransform.concatenate(scaling);
imageTransform.concatenate(resolutionScaling);
//Now that we have the full baseTransform, we can update the transformation matrix for
//the AElementBridge.
PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge(
SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG);
aBridge.getCurrentTransform().setTransform(baseTransform);

/*
* Clip to the svg area.
* Note: To have the svg overlay (under) a text area then use
@@ -236,7 +222,7 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler
pdfInfo.currentStream.add(CTMHelper.toPDFString(scaling, false) + " cm\n");
}

SVGSVGElement svg = ((SVGDocument)doc).getRootElement();
//SVGSVGElement svg = ((SVGDocument)doc).getRootElement();

if (pdfInfo.pdfContext == null) {
pdfInfo.pdfContext = pdfInfo.pdfPage;
@@ -248,7 +234,8 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());

if (!resolutionScaling.isIdentity()) {
pdfInfo.currentStream.add("%resolution scaling for " + uaResolution + " -> " + deviceResolution + "\n");
pdfInfo.currentStream.add("%resolution scaling for " + uaResolution
+ " -> " + deviceResolution + "\n");
pdfInfo.currentStream.add(
CTMHelper.toPDFString(resolutionScaling, false) + " cm\n");
graphics.scale(1 / s, 1 / s);
@@ -256,8 +243,16 @@ public class PDFSVGHandler extends AbstractGenericSVGHandler
pdfInfo.currentStream.add("%SVG start\n");

//Save state and update coordinate system for the SVG image
pdfInfo.pdfState.push();
pdfInfo.pdfState.setTransform(baseTransform);
pdfInfo.pdfState.concatenate(imageTransform);

//Now that we have the complete transformation matrix for the image, we can update the
//transformation matrix for the AElementBridge.
PDFAElementBridge aBridge = (PDFAElementBridge)ctx.getBridge(
SVGDOMImplementation.SVG_NAMESPACE_URI, SVGConstants.SVG_A_TAG);
aBridge.getCurrentTransform().setTransform(pdfInfo.pdfState.getTransform());

graphics.setPDFState(pdfInfo.pdfState);
graphics.setOutputStream(pdfInfo.outputStream);
try {

+ 1
- 1
src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java Visa fil

@@ -355,7 +355,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
scale(1 / s, 1 / s);
}
// Remember the transform we installed.
graphicsState.setTransform(at);
graphicsState.concatenate(at);

pdfContext.increasePageCount();
}

+ 4
- 0
status.xml Visa fil

@@ -28,6 +28,10 @@

<changes>
<release version="FOP Trunk">
<action context="Code" dev="JM" type="fix">
Bugfix: Corrected painting of shading patterns and position of links for SVG images
inside FO documents.
</action>
<action context="Code" dev="AD" type="update">
Minor fix: correctly set negative values to zero.
</action>

Laddar…
Avbryt
Spara