Skip to content

Plugins: SVG Images

Daniel Rezek edited this page Jul 19, 2021 · 9 revisions

Simple example

<html>
<body>

<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg> 
 
</body>
</html>
public static void main(String... args) throws Exception { 
        try (OutputStream os = new FileOutputStream("/Users/me/Documents/pdf-issues/output/circle.pdf")) {
            PdfRendererBuilder builder = new PdfRendererBuilder();
            builder.withUri("file:///Users/me/Documents/pdf-issues/circle.html");
            builder.useFastMode();
            builder.toStream(os);
            builder.useSVGDrawer(new BatikSVGDrawer()); // Load SVG support plugin
            builder.run();
        }
}
  	<dependency>
  		<!-- SVG support plugin. -->
  		<groupId>com.openhtmltopdf</groupId>
  		<artifactId>openhtmltopdf-svg-support</artifactId>
  		<version>${openhtml.version}</version>
  	</dependency>

Notes

  • The svg element must include the namespace attribute: xmlns="http://www.w3.org/2000/svg"
  • SVG content, like other XML, should only come from a trusted source.
  • From RC21, the default constructor for BatikSVGDrawer hooks into Batik to disallow scripts and external resource requests. If you'd like the old behavior that allowed external resource requests (including file://) and possibly scripts please use the new constructor: builder.useSVGDrawer(new BatikSVGDrawer(SvgScriptMode.INSECURE_ALLOW_SCRIPTS, SvgExternalResourceMode.INSECURE_ALLOW_EXTERNAL_RESOURCE_REQUESTS));.
  • For info on using fonts with SVG, see fonts page.
  • From RC15, if you have the SVG plugin loaded and an external image ends with .svg it will be rendered as SVG.

SVG sizing

  • The size of the SVG box is determined by CSS and attributes in the following order, from highest priority to lowest:
    • min-width/min-height CSS properties
    • max-width/max-height CSS properties
    • width/height CSS properties
    • width/height attributes (unit-less integers declaring the size in pixels)
    • viewBox attribute (four unit-less integers, the last two of which are treated as declaring the size in pixels)
    • default dimensions (400px x 400px)
  • The actual SVG image will ONLY be scaled to fit the box if the size is provided by CSS properties AND either the width and height attributes are valid or a valid viewBox attribute is provided.
  • The aspect ratio of the image will always be preserved.

SVG Sprites

Openhtmltopdf supports sprites. You can use it like this (note this example requires external resource requests to be enabled):

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20">
   <use xlink:href="img/sprites/brands.svg#my-awesome-brand"></use>
</svg>

Pay attention if using relative (img/sprite.svg) or absolute (/img/sprite.svg) paths. You can also use a remote file for a sprite: <use xlink:href="http://localhost:8080/img/sprites/solid.svg#my-sprite" ></use>

Open issues

  • min-height/min-width are not implemented. Implemented in version 1.0.0.
  • Chrome seems to use display: inline-block while we use a default of block.
  • Chrome seems to only scale if a viewBox attribute is present while we also scale if width/height attributes are provided.
  • page-break-inside: avoid is ignored on svg elements and they can be rendered over two or more pages.
  • URIs (for content such as raster images) in the SVG will NOT be resolved through any URI resolver configured on the builder see https://github.com/danfickle/openhtmltopdf/issues/444. Implemented in 1.0.3.
  • Multiple identical SVGs are not cached, even if included using the img tag.