Skip to content

Commit

Permalink
For #23 - Finally implements SVG transforms and the correct transform…
Browse files Browse the repository at this point in the history
… origin.

At least when it comes to SVG transforms, we are now matching Chrome.
  • Loading branch information
danfickle committed Jun 22, 2016
1 parent 0a412c8 commit 99c1a64
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.RenderingHints.Key;
import java.awt.geom.AffineTransform;

import com.openhtmltopdf.css.parser.FSColor;
import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.css.style.derived.BorderPropertySet;
Expand All @@ -44,9 +42,6 @@ public interface OutputDevice {
public void saveState();
public void restoreState();

public void setDeviceTransform(AffineTransform transform);
public AffineTransform getDeviceTransform();

public void setPaint(Paint paint);
public void setAlpha(int alpha);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.openhtmltopdf.render.RenderingContext;

public interface SVGDrawer {
public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y);
public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y, float dotsPerInch);

public void importFontFaceRules(List<FontFaceRule> fontFaces, SharedContext shared);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.awt.Stroke;
import java.awt.RenderingHints.Key;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

Expand Down Expand Up @@ -303,17 +302,6 @@ public void restoreState() {

}

@Override
public void setDeviceTransform(AffineTransform transform) {
// TODO Auto-generated method stub
}

@Override
public AffineTransform getDeviceTransform() {
// TODO
return null;
}

@Override
public void setPaint(Paint paint) {
// TODO Auto-generated method stub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ public class PdfBoxOutputDevice extends AbstractOutputDevice implements OutputDe
private RenderingContext _renderingContext;

private BidiReorderer _reorderer = new SimpleBidiReorderer();

private AffineTransform _deviceTransform;
private AffineTransform _setDeviceTransform = new AffineTransform();

public PdfBoxOutputDevice(float dotsPerPoint, boolean testMode) {
_dotsPerPoint = dotsPerPoint;
Expand Down Expand Up @@ -589,8 +586,6 @@ private void followPath(Shape s, int drawType) {
} else if (drawType == FILL) {
ensureFillColor();
}

ensureDeviceTransform();

PathIterator points;
if (drawType == CLIP) {
Expand Down Expand Up @@ -1278,34 +1273,6 @@ public void restoreState() {
_cp.restoreGraphics();
}

/**
* This converts the x and y translate variables to pdf device units.
* Remember, PDFs use a bottom to top coordinate system.
*/
private AffineTransform normalizeDeviceMatrix(AffineTransform current) {
double[] mx = new double[6];
current.getMatrix(mx);
mx[5] *= -1;
return new AffineTransform(mx);
}

private void ensureDeviceTransform() {
if (!(_deviceTransform == null || _deviceTransform.isIdentity())) {
_setDeviceTransform = _deviceTransform;
_cp.setPdfMatrix(normalizeDeviceMatrix(_setDeviceTransform));
}
}

@Override
public AffineTransform getDeviceTransform() {
return _deviceTransform;
}

@Override
public void setDeviceTransform(AffineTransform transform) {
_deviceTransform = transform;
}

@Override
public void setPaint(Paint paint) {
if (paint instanceof Color) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ public int getBaseline() {

@Override
public void paint(RenderingContext c, PdfBoxOutputDevice outputDevice, BlockBox box) {
svg.drawSVG(e, outputDevice, c, point.getX(), point.getY());
svg.drawSVG(e, outputDevice, c, point.getX(), point.getY(), this.dotsPerPixel * 96f);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ public void importFontFaceRules(List<FontFaceRule> fontFaces, SharedContext shar
}

@Override
public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y) {
public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y, float dotsPerInch) {

if (this.fontResolver == null) {
XRLog.general(Level.INFO, "importFontFaceRules has not been called for this pdf transcoder");
this.fontResolver = new OpenHtmlFontResolver();
}

PDFTranscoder transcoder = new PDFTranscoder(outputDevice, ctx, x, y, this.fontResolver);
PDFTranscoder transcoder = new PDFTranscoder(outputDevice, ctx, x, y, this.fontResolver, dotsPerInch);

try {
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,31 @@

public class PDFGraphics2DOutputDeviceAdapter extends AbstractGraphics2D {

private static final int DEFAULT_DOTS_PER_PIXEL = 20;

private final RenderingContext ctx;
private final OutputDevice od;
private final Graphics2D g2d2;
private final double x;
private final double y;
private final AffineTransform defaultTransform;
private final float dotsPerPoint;

private Color _c = Color.BLACK;
private Stroke _stroke;
private Paint _paint = Color.BLACK;
private Composite _composite = AlphaComposite.getInstance(AlphaComposite.SRC);
private Color _background = Color.WHITE;
private final AffineTransform scaleToPdf;

public PDFGraphics2DOutputDeviceAdapter(RenderingContext ctx, OutputDevice od, double x, double y) {
public PDFGraphics2DOutputDeviceAdapter(RenderingContext ctx, OutputDevice od, double x, double y, float dotsPerInch) {
super(false);

this.od = od;
this.ctx = ctx;
this.x = x;
this.y = y;
this.dotsPerPoint = dotsPerInch / 96f;

AffineTransform locate = AffineTransform.getTranslateInstance(x, y);
AffineTransform scale = AffineTransform.getScaleInstance(DEFAULT_DOTS_PER_PIXEL, DEFAULT_DOTS_PER_PIXEL);
scaleToPdf = new AffineTransform(); // I belive both SVG Batik and our PDFs use 96 dpi.
locate.concatenate(scale);
locate.concatenate(scaleToPdf);
defaultTransform = locate;
AffineTransform scale = AffineTransform.getScaleInstance(dotsPerPoint, dotsPerPoint);
defaultTransform = scale;

BufferedImage img = new BufferedImage(BufferedImage.TYPE_INT_ARGB, 1, 1);
g2d2 = img.createGraphics();
Expand Down Expand Up @@ -166,37 +161,35 @@ public void drawString(AttributedCharacterIterator iterator, float x, float y) {
@Override
public void draw(Shape s) {
Color c = getColor();

od.setColor(new FSRGBColor(c.getRed(), c.getGreen(), c.getBlue()));
od.setAlpha(c.getAlpha());

if (!getTransform().isIdentity()) {
// TODO: Transform origin.
//od.setDeviceTransform(getTransform());
}

od.setStroke(getStroke());
od.setPaint(getPaint());

AffineTransform offsetTransform = new AffineTransform(defaultTransform);
offsetTransform.translate(this.x / this.dotsPerPoint, this.y / this.dotsPerPoint);
offsetTransform.concatenate(getTransform());

od.saveState();
od.draw(defaultTransform.createTransformedShape(s));
od.draw(offsetTransform.createTransformedShape(s));
od.restoreState();
}

@Override
public void fill(Shape s) {
Color c = getColor();
od.setColor(new FSRGBColor(c.getRed(), c.getGreen(), c.getBlue()));

od.setColor(new FSRGBColor(c.getRed(), c.getGreen(), c.getBlue()));
od.setAlpha(c.getAlpha());

if (!getTransform().isIdentity()) {
// TODO: Transform origin.
//od.setDeviceTransform(getTransform());
}

od.setPaint(getPaint());

AffineTransform offsetTransform = new AffineTransform(defaultTransform);
offsetTransform.translate(this.x / this.dotsPerPoint, this.y / this.dotsPerPoint);
offsetTransform.concatenate(getTransform());

od.saveState();
od.fill(defaultTransform.createTransformedShape(s));
od.fill(offsetTransform.createTransformedShape(s));
od.restoreState();
}

Expand Down Expand Up @@ -238,7 +231,7 @@ public Rectangle getBounds() {

@Override
public Graphics create() {
return new PDFGraphics2DOutputDeviceAdapter(ctx, od, x, y);
return new PDFGraphics2DOutputDeviceAdapter(ctx, od, x, y, this.dotsPerPoint * 96f);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class PDFTranscoder extends SVGAbstractTranscoder {
private final PDFGraphics2DOutputDeviceAdapter od;
private final OpenHtmlFontResolver fontResolver;

public PDFTranscoder(OutputDevice od, RenderingContext ctx, double x, double y, OpenHtmlFontResolver fontResolver) {
this.od = new PDFGraphics2DOutputDeviceAdapter(ctx, od, x, y);
public PDFTranscoder(OutputDevice od, RenderingContext ctx, double x, double y, OpenHtmlFontResolver fontResolver, float dotsPerInch) {
this.od = new PDFGraphics2DOutputDeviceAdapter(ctx, od, x, y, dotsPerInch);
this.fontResolver = fontResolver;
}

Expand Down

0 comments on commit 99c1a64

Please sign in to comment.