--- title: "Updating Graphics Devices for R 4.2.0" author: "Paul Murrell" date: 2021-12-14 categories: ["Internals"] tags: ["graphics"] ---
A number of new graphics features have been added to the R graphics
engine in the development version of R (to become version 4.2.0):
groups, compositing operators, affine
transformations, stroking and filling paths, and luminance masks.
This has consequences for R packages that provide graphics devices,
like the ‘ragg’ package.
For users of R packages that provide graphics devices, those packages will need to be reinstalled when updating to R 4.2.0.
For the maintainers of R packages that provide graphics devices, this document describes the changes that are necessary to update a graphics device package in preparation for R 4.2.0.
All an R user should need to know is to reinstall graphics device packages; the rest of this document is more technical and aimed at R developers who maintain graphics device packages.
The first option is easy: do nothing.
With the addition of the deviceVersion
for graphics devices,
the graphics engine is able to detect that a graphics device
has not been updated and it will not ask a device to do things
that it does not support.
The only problem that should occur is if the graphics device package
is not reinstalled, and the package uses R_GE_checkVersionOrDie()
,
then the package will fail with a “version mismatch” error.
The solution in that case will be to reinstall the graphics device.
The second option is also relatively easy: do almost nothing.
This option involves updating the graphics device package
to set the deviceVersion
to 15 (R_GE_group
), but
without providing support for any of the new features.
The new graphics engine version requires that the graphics device provides the following new device callbacks:
defineGroup()
useGroup()
releaseGroup()
stroke()
fill()
fillStroke()
capabilities()
In each case, it is possible to provide a stub that does nothing. The graphics engine will call the device, but there will just be no output produced.
The postscript()
graphics device provides a template for this
approach. A graphics device package can model its device
callbacks on functions like PS_defineGroup()
in devPS.c
.
A more ambitious variant of this option is to provide support for just a subset of the new features; that is also a less ambitious variant of the next option …
This option is a lot harder: add support for the new features.
For some graphics devices, this will not be an option because the
language or library underlying the graphics device does not
support the new features. The xfig()
device is an example.
Where it is possible to add support, the purpose of each of the new device callbacks is (briefly):
defineGroup(source, op, destination)
should run the R function
destination
, set the compositing operator op
, then run the R
function source
, recording all drawing that occurs as a result
off-screen, and return a reference to the recorded drawing.useGroup(ref, trans)
should apply the transformation matrix trans
and render the recorded drawing referenced by ref
.releaseGroup(ref)
can release resources associated with the
recorded drawing referenced by ref
.stroke(path)
should run the R function path
, recording all
drawing as a path, then stroke the path.fill(path, rule)
should run the R function path
, recording all
drawing as a path, then fill the path using the fill rule
.fillStroke(path, rule)
should run the R function path
, recording all
drawing as a path, then fill and stroke the path using the fill rule
.capabilities(capabilities)
should modify components of the list
capabilities
to indicate the level of support provided by the device.The pdf()
device and the devices based on the Cairo graphics library,
e.g., png(type="cairo")
and svg()
,
provide exemplars of devices that have implemented support for the
new features. See, for example, PDF_defineGroup()
in devPS.c
and Cairo_DefineGroup()
in cairoFns.c
.
The “Graphics Devices” Section
of the “R Internals” Manual also
contains some more detailed information, particularly about the
capabilities()
device callback.
Further discussion and more detail about the new features and how they have been implemented can be found in a series of technical reports: one on groups, one on paths, and one on masks.