Skip to content

Commit

Permalink
For #23 - First stage of SVG cleanup.
Browse files Browse the repository at this point in the history
- Correctly deal with width and height of SVG elements.
- Add svg as block element to the base stylesheet (only block elements
can be replaced).
- Import fonts once per document rather than for every SVG element.
  • Loading branch information
danfickle committed Jun 18, 2016
1 parent bb586a9 commit 91da4d2
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<FontFaceRule> fontFaces);
public void importFontFaceRules(List<FontFaceRule> 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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -47,8 +61,6 @@ public void setLocation(int x, int y) {

@Override
public void detach(LayoutContext c) {
// TODO Auto-generated method stub

}

@Override
Expand All @@ -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());
}

}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<FontFaceRule> rules;
public OpenHtmlFontResolver fontResolver;

@Override
public void importFontFaceRules(List<FontFaceRule> fontFaces) {
this.rules = fontFaces;
public void importFontFaceRules(List<FontFaceRule> 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();
Expand Down Expand Up @@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, OpenHtmlGvtFontFamily> families = new HashMap<String, OpenHtmlGvtFontFamily>(4);
private final SharedContext ctx;

public OpenHtmlFontResolver(SharedContext ctx) {
this.ctx = ctx;
}


@Override
public GVTFontFamily resolve(String arg0, FontFace arg1) {
return null;
Expand Down Expand Up @@ -134,7 +129,7 @@ private void addFontFaceFont(
}


public void importFontFaces(List<FontFaceRule> fontFaces) {
public void importFontFaces(List<FontFaceRule> fontFaces, SharedContext ctx) {
for (FontFaceRule rule : fontFaces) {
CalculatedStyle style = rule.getCalculatedStyle();

Expand Down

0 comments on commit 91da4d2

Please sign in to comment.