diff --git a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/SVGDrawer.java b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/SVGDrawer.java index 72b7a210f..ae9f5d9ae 100644 --- a/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/SVGDrawer.java +++ b/openhtmltopdf-core/src/main/java/com/openhtmltopdf/extend/SVGDrawer.java @@ -9,7 +9,19 @@ import com.openhtmltopdf.render.RenderingContext; public interface SVGDrawer { - public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y, SharedContext shared); + public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y); - public void importFontFaceRules(List fontFaces); + public void importFontFaceRules(List fontFaces, SharedContext shared); + + /** + * @param e the SVG element + * @return the width of the SVG in pixels. + */ + public int getSVGWidth(Element e); + + /** + * @param e the SVG element + * @return the height of the SVG in pixels. + */ + public int getSVGHeight(Element e); } diff --git a/openhtmltopdf-core/src/main/resources/resources/css/XhtmlNamespaceHandler.css b/openhtmltopdf-core/src/main/resources/resources/css/XhtmlNamespaceHandler.css index 095274c41..112a19645 100644 --- a/openhtmltopdf-core/src/main/resources/resources/css/XhtmlNamespaceHandler.css +++ b/openhtmltopdf-core/src/main/resources/resources/css/XhtmlNamespaceHandler.css @@ -6,7 +6,7 @@ frame, frameset, h1, h2, h3, h4, h5, h6, noframes, ol, p, ul, center, -dir, hr, menu, pre, object { display: block } +dir, hr, menu, pre, object, svg { display: block } li { display: list-item } head, script { display: none } body { margin: 8px } diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java index a764ca3bb..8df8c2a49 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxRenderer.java @@ -258,7 +258,7 @@ public void setDocument(Document doc, String url, NamespaceHandler nsh) { getFontResolver().importFontFaces(_sharedContext.getCss().getFontFaceRules()); if (_svgImpl != null) { - _svgImpl.importFontFaceRules(_sharedContext.getCss().getFontFaceRules()); + _svgImpl.importFontFaceRules(_sharedContext.getCss().getFontFaceRules(), _sharedContext); } } diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java index 6faf4fc65..fda254ddc 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxReplacedElementFactory.java @@ -28,7 +28,6 @@ import com.openhtmltopdf.extend.UserAgentCallback; import com.openhtmltopdf.layout.LayoutContext; import com.openhtmltopdf.render.BlockBox; -import com.openhtmltopdf.render.RenderingContext; import com.openhtmltopdf.simple.extend.FormSubmissionListener; public class PdfBoxReplacedElementFactory implements ReplacedElementFactory { @@ -51,8 +50,7 @@ public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, if (nodeName.equals("svg") && _svgImpl != null) { - // TODO: Correct width and height - return new PdfBoxSVGReplacedElement(e, _svgImpl, cssWidth, cssHeight); + return new PdfBoxSVGReplacedElement(e, _svgImpl, cssWidth, cssHeight, c.getSharedContext().getDotsPerPixel()); } else if (nodeName.equals("img")) { String srcAttr = e.getAttribute("src"); diff --git a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSVGReplacedElement.java b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSVGReplacedElement.java index 95c84a9d5..8baa9891b 100644 --- a/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSVGReplacedElement.java +++ b/openhtmltopdf-pdfbox/src/main/java/com/openhtmltopdf/pdfboxout/PdfBoxSVGReplacedElement.java @@ -15,24 +15,38 @@ public class PdfBoxSVGReplacedElement implements PdfBoxReplacedElement { private Point point = new Point(0, 0); private final int width; private final int height; + private final int dotsPerPixel; - public PdfBoxSVGReplacedElement(Element e, SVGDrawer svgImpl, int cssWidth, int cssHeight) { + public PdfBoxSVGReplacedElement(Element e, SVGDrawer svgImpl, int cssWidth, int cssHeight, int dotsPerPixel) { this.e = e; this.svg = svgImpl; this.width = cssWidth; this.height = cssHeight; + this.dotsPerPixel = dotsPerPixel; } @Override public int getIntrinsicWidth() { - // TODO Auto-generated method stub - return 10000; // TOTAL GUESS. + if (this.width >= 0) { + // CSS takes precedence over width and height defined on element. + return this.width; + } + else { + // Seems to need dots rather than pixels. + return this.svg.getSVGWidth(e) * this.dotsPerPixel; + } } @Override public int getIntrinsicHeight() { - // TODO Auto-generated method stub - return 10000; // TOTAL GUESS. + if (this.height >= 0) { + // CSS takes precedence over width and height defined on element. + return this.height; + } + else { + // Seems to need dots rather than pixels. + return this.svg.getSVGHeight(e) * this.dotsPerPixel; + } } @Override @@ -47,8 +61,6 @@ public void setLocation(int x, int y) { @Override public void detach(LayoutContext c) { - // TODO Auto-generated method stub - } @Override @@ -68,7 +80,6 @@ public int getBaseline() { @Override public void paint(RenderingContext c, PdfBoxOutputDevice outputDevice, BlockBox box) { - svg.drawSVG(e, outputDevice, c, point.getX(), point.getY(), ((PdfBoxOutputDevice) outputDevice).getSharedContext()); + svg.drawSVG(e, outputDevice, c, point.getX(), point.getY()); } - } diff --git a/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/BatikSVGDrawer.java b/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/BatikSVGDrawer.java index 762298a96..5037adec4 100644 --- a/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/BatikSVGDrawer.java +++ b/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/BatikSVGDrawer.java @@ -1,6 +1,7 @@ package com.openhtmltopdf.svgsupport; import java.util.List; +import java.util.logging.Level; import org.apache.batik.anim.dom.SVGDOMImplementation; import org.apache.batik.transcoder.TranscoderException; @@ -15,23 +16,30 @@ import com.openhtmltopdf.extend.SVGDrawer; import com.openhtmltopdf.layout.SharedContext; import com.openhtmltopdf.render.RenderingContext; +import com.openhtmltopdf.svgsupport.PDFTranscoder.OpenHtmlFontResolver; import com.openhtmltopdf.util.XRLog; public class BatikSVGDrawer implements SVGDrawer { private static final String DEFAULT_VP_WIDTH = "400"; private static final String DEFAULT_VP_HEIGHT = "400"; - private List rules; + public OpenHtmlFontResolver fontResolver; @Override - public void importFontFaceRules(List fontFaces) { - this.rules = fontFaces; + public void importFontFaceRules(List fontFaces, SharedContext shared) { + this.fontResolver = new OpenHtmlFontResolver(); + this.fontResolver.importFontFaces(fontFaces, shared); } @Override - public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y, SharedContext shared) { - PDFTranscoder transcoder = new PDFTranscoder(outputDevice, ctx, x, y, shared); - transcoder.fontResolver.importFontFaces(rules); + public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingContext ctx, double x, double y) { + + 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); try { DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); @@ -63,4 +71,34 @@ public void drawSVG(Element svgElement, OutputDevice outputDevice, RenderingCont XRLog.exception("Couldn't draw SVG.", e); } } + + private int parseOrDefault(String num, int def) { + try { + return Integer.parseInt(num); + } catch (NumberFormatException e) + { + XRLog.general(Level.WARNING, "Invalid integer passed as dimension for SVG: " + num); + return def; + } + } + + @Override + public int getSVGWidth(Element e) { + if (e.hasAttribute("width")) { + return parseOrDefault(e.getAttribute("width"), Integer.parseInt(DEFAULT_VP_WIDTH)); + } + else { + return Integer.parseInt(DEFAULT_VP_WIDTH); + } + } + + @Override + public int getSVGHeight(Element e) { + if (e.hasAttribute("height")) { + return parseOrDefault(e.getAttribute("height"), Integer.parseInt(DEFAULT_VP_HEIGHT)); + } + else { + return Integer.parseInt(DEFAULT_VP_HEIGHT); + } + } } diff --git a/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/PDFTranscoder.java b/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/PDFTranscoder.java index 2361edb63..bdb6ffd33 100644 --- a/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/PDFTranscoder.java +++ b/openhtmltopdf-svg-support/src/main/java/com/openhtmltopdf/svgsupport/PDFTranscoder.java @@ -29,21 +29,16 @@ public class PDFTranscoder extends SVGAbstractTranscoder { private final PDFGraphics2DOutputDeviceAdapter od; - public final OpenHtmlFontResolver fontResolver; + private final OpenHtmlFontResolver fontResolver; - public PDFTranscoder(OutputDevice od, RenderingContext ctx, double x, double y, SharedContext shared) { + public PDFTranscoder(OutputDevice od, RenderingContext ctx, double x, double y, OpenHtmlFontResolver fontResolver) { this.od = new PDFGraphics2DOutputDeviceAdapter(ctx, od, x, y); - this.fontResolver = new OpenHtmlFontResolver(shared); + this.fontResolver = fontResolver; } public static class OpenHtmlFontResolver implements FontFamilyResolver { private final Map families = new HashMap(4); - private final SharedContext ctx; - - public OpenHtmlFontResolver(SharedContext ctx) { - this.ctx = ctx; - } - + @Override public GVTFontFamily resolve(String arg0, FontFace arg1) { return null; @@ -134,7 +129,7 @@ private void addFontFaceFont( } - public void importFontFaces(List fontFaces) { + public void importFontFaces(List fontFaces, SharedContext ctx) { for (FontFaceRule rule : fontFaces) { CalculatedStyle style = rule.getCalculatedStyle();