Scaling SVG outputs
The SVG files produced by svglite do not include width
and height
properties. This is a deliberate choice intended
to make it easier to fit fluidly a SVG figure to its enclosing
container. The scaling straightforward but requires some understanding
of the viewBox
SVG attribute which is included in all SVGs
produced by svglite. This property defines the aspect ratio of the plot
(as well as a user coordinate system, see next section).
Fluid scaling
The viewBox is determined by the width
and
height
arguments of svglite’s device functions (with 10’’ x
8’’ the default). Although those dimensions are supplied in inches, the
viewBox’s user coordinate system is completely unit agnostic. The main
effect is thus to determine an aspect ratio. Since dimensions are not
provided, the dimensions of the enclosing container are used instead and
the SVG is rescaled to fit the container (although Internet Explorer
currently requires some CSS tricks to get this behaviour, see https://tympanus.net/codrops/2014/08/19/making-svgs-responsive-with-css/).
Aspect ratio is preserved by default when the figure is scaled up or
down. The details of how the aspect ratio is preserved can be adjusted
in multiple ways via the preserveAspectRatio
attribute. See
https://www.sarasoueidan.com/blog/svg-coordinate-systems/
for more information about this property.
Other useful resource: https://css-tricks.com/scale-svg/
Natural scaling
Another strategy is needed in order to scale the figure to make the text within the SVG consistent with the text in the surrounding web page. That could be useful, for instance, to create a consistent appearance in an HTML presentation. Since the user coordinate system defined by the viewBox is unitless, we need to map the figure to its natural dimensions. This will ensure a correspondence between the scale of the figure and that of the web page.
As mentioned above, the natural scale of svglite’s figures is in
points and is determined by the width
and
height
arguments that you supply to the device functions
(10’’ x 8’’ being the default). Although those dimensions are specified
in inches, the coordinate system is scaled in points. Counting 72 points
per inch, the default SVG surface is thus 720 x 576 pt. Note that the
CSS standard defines 12pt to be equal to 16px, the default size of text
in most browsers. Since 12pt is the default text size in svglite as
well, a SVG scaled to its natural dimensions will appear seamless with
web text of 16px. If the text in your web page has another size, you
will have to compute a scale factor and adjust the dimensions of the SVG
accordingly.
To sum up, displaying a plot according to its natural dimensions
requires providing the user agent with information about what the
lengths defined within the SVG actually mean. There are several ways to
achieve this. First you can edit the SVG and enclose it in another pair
of <svg>
tags that defines height
and
width
. The root <svg>
element determines
the final dimensions of the figure.
A second way is to enclose the figure in a <div>
tag with appropriate dimensions and let the SVG figure rescale itself to
that container (cf. the section on fluid scaling):
Finally, you can directly specify the dimensions in the
<img>
or <object>
tag that is
embedding the figure. Note that the dimension attributes of those tags
do not accept arbitrary units, so you will have to supply the dimensions
in pixels. Just multiply the width and height measured in points with a
factor of 16/12:
Internal notes
Device scaling
As other graphics devices, svglite is scaled in big points (1/72
inch) rather than pica points (1/72.27 inch). Note that in LaTeX and in
the grid
graphics system on which ggplot2 is based, points
refer to pica points. Big points are denoted in LaTeX by bp
and in CSS by pt
. We use the latter notation. See https://tex.stackexchange.com/a/200968/19755 for some
historical background about these units.
The conversion between device units and physical dimensions is
determined by the DevDesc parameter ipr
. IPR stands for
inches per raster (native device coordinates are sometimes called
rasters in R terminology) and is set to 1/72 in svglite. The device’s
physical dimensions are set by the following DevDesc parameters (with
width
and height
the plot dimensions set by
the user in inches):
Parameter | Value |
---|---|
left |
0 |
top |
0 |
right |
width * 72 |
bottom |
height * 72 |
A default svglite plot surface is thus 720 x 576 pt.
Scaling of graphical elements
It is conventional for the fundamental line width
(lwd = 1
) to correspond to a line width of 1/96 inch and
svglite obeys this convention. Also, like other R graphics devices,
svglite interprets all point sizes directly as big points (e.g. the
ps
graphical parameter and the fontsize
argument of device functions). The default font size is 12pt.
Text metrics are computed by systemfonts, which uses freetype to
extract metrics for each glyph and calculate string dimensions from
that. Text metrics are calculated at 1000dpi based on
cex * ps
font size.
The Base graphics system also makes use of the obscure
cra
parameter and its relatives (cin
,
cxy
, and csi
). cra
serves as a
crude measure for a default character height and width for the default
fontsize provided when the device is called (12pt in svgilte). The main
effect of this parameter (more specifically, the height component) is to
change the relationship between the margin parameters
mar
/mai
and oma
/omi
.
The margins mar
and oma
are specified in line
units and character height is used as a measure of line spacing to
convert margins measured in lines to physical margins. As in other
devices, cra[0]
is set to 0.9 * pointsize
and
cra[1]
to 1.2 * pointsize
. These parameters
are completely unused in the Grid graphics system.
SVG output
The SVG output sets up a viewBox (a user coordinate system) with values scaled in big points.
viewBox: The width and height are set to
dd->right
and dd->bottom
respectively
(these values are determined by the user-supplied figure
width
and height
).
Line width: 1 lwd
should equal 1/96
inch. svglite gets values scaled in device coordinates (big points), so
the line width is multiplied by 72/96.
Text: gdtools returns metrics scaled in big points
so no transformation is needed. We do need to add px
units
to work around a rendering bug in Firefox. Note that when a viewBox is
set up, a pixel equals one unit in the user coordinate system and thus
actually represents a big point.