SVG and DPI, absolute units and user units: Inkscape vs. Firefox vs. ImageMagick

Viewed 24222

I try to auto-generate an SVG file intended to be printed on a certain size (A4). I wish to use a path in it, which only allows 'user units', not 'absolute units'.

It seems to me that it is impossible to 'publish' an SVG file that has absolute units (e.g. document size) and a path anywhere, because I cannot get it to work properly across viewers.

Is there a way to get some consistency in rendering, like specifying a 'default DPI'?

Or put differently: Can I get my example below to render the same in all viewers without abandoning absolute units at all?

Related: Is there a way to force any of the applications below to render the image in the same way as one of the others? (E.g. I tried the -density option of 'convert', but I couldn't get the output to match Inkscape's or Firefox' output.)


Example:

I've created one SVG file, with three black squares (rect) with a red diagonal (path):

  • Left: square and diagonal in user units
  • Middle: square and diagonal in inch (seemed to me the most logical choice, but is not allowed)
  • Right: square in mm, diagonal in user units

Which renders differently in different viewers:

  • Inkscape: 90 DPI, all squares same size, red diagonal matches
  • Firefox: 96 DPI?, latter squares to large (or diagonal to short)
  • Convert: 72 DPI, latter squares to small (or diagonal to long)

Code:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="200mm"
   height="100mm"
   >
  <g transform="translate(50,50)">
    <rect
       width="100."
       height="100."
       x="10"
       y="10" />
    <path style="stroke: #ff0000" d="M 10 10 L 110 110" />
  </g>
  <g transform="translate(200,50)">
    <rect
       width="1.111in"
       height="1.111in"
       x="0.1111in"
       y="0.1111in" />
    <path style="stroke: #ff0000" d="M 0.1111in 0.1111in L 1.111in 1.111in" />
  </g>
  <g transform="translate(350,50)">
    <rect
       width="1.111in"
       height="1.111in"
       x="0.1111in"
       y="0.1111in" />
    <path style="stroke: #ff0000" d="M 10 10 L 110 110" />
  </g>
</svg>

Inkscape (my default 'viewer'):

Alt text

Firefox (note that the red line does not reach the lower right corner. I made a screenshot and cropped sort of arbitrarily):

Firefox

ImageMagick (convert, no options besides filenames given):

Alt text

2 Answers

All dimensions in a path tag are in user units.

You cannot specify absolute units within a path tag, which is why the path in the middle square does not render.

The simplest way I have found is to set the units using viewbox:

  • Set the width & height in inches.
  • Then set the viewbox to be the same.
  • This sets the user unit to be one inch.
  • All sizes are then specified in inches (note: I used lower case l in path tag to specify a relative move)

This displays correctly in Inkscape and Firefox.

<svg
    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    width="8in"
    height="4in"
    viewBox="0 0 8 4">

    <g transform="translate(4,0.5)">
        <rect
            width="1.111"
            height="1.111"
            x="0.1111"
            y="0.1111" />
        <path d="M 0.1111,0.1111 l 1.111 1.111" style="stroke: #ff0000;stroke-width:0.01"  />
    </g>
</svg>
Related