svglite
svglite copied to clipboard
user_fonts doesn't appear to work
Excellent package with brilliant results, but I need a way to use web fonts or failing that embed fonts to get the same experience across platforms. The user_fonts
argument should do the latter of these if I understand the vignette properly, but the example in the vignette does work for me.
Here is the code:
library(svglite)
# Using ttf files from fontquiver here, but it could be any ttf
some_file <- fontquiver::font("Liberation", "Sans", "Regular")$ttf
other_file <- fontquiver::font("Liberation", "Sans", "Italic")$ttf
serif_file <- fontquiver::font("Liberation", "serif", "Italic")$ttf
# The outer named list contains families while the inner named list
# contains faces:
lib_fonts <- list(
sans = list(
plain = some_file,
italic = other_file
),
serif = list(plain = serif_file)
)
svglite("plot.svg", user_fonts = lib_fonts)
plot.new()
par(cex = 1.5)
text(0.5, 0.5, "Sans Plain text")
text(0.2, 0.2, "Sans Italic text", font = 3)
text(0.8, 0.8, "Serif text", family = "serif")
dev.off()
and here is how it looks; all typeface families are a generic serif:
Or if you inspect the code of the svg:
<?xml version='1.0' encoding='UTF-8' ?>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 720.00 576.00'>
<defs>
<style type='text/css'><![CDATA[
line, polyline, path, rect, circle {
fill: none;
stroke: #000000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-miterlimit: 10.00;
}
]]></style>
</defs>
<rect width='100%' height='100%' style='stroke: none; fill: #FFFFFF;'/>
<defs>
<clipPath id='cpNTkuMDR8Njg5Ljc2fDUwMi41Nnw1OS4wNA=='>
<rect x='59.04' y='59.04' width='630.72' height='443.52' />
</clipPath>
</defs>
<g clip-path='url(#cpNTkuMDR8Njg5Ljc2fDUwMi41Nnw1OS4wNA==)'><text x='314.37' y='287.24' style='font-size: 18.00px; font-family: sans;' textLength='120.07px' lengthAdjust='spacingAndGlyphs'>Sans Plain text</text></g>
<g clip-path='url(#cpNTkuMDR8Njg5Ljc2fDUwMi41Nnw1OS4wNA==)'><text x='140.67' y='410.44' style='font-size: 18.00px; font-style: italic; font-family: sans;' textLength='117.05px' lengthAdjust='spacingAndGlyphs'>Sans Italic text</text></g>
<g clip-path='url(#cpNTkuMDR8Njg5Ljc2fDUwMi41Nnw1OS4wNA==)'><text x='517.36' y='162.02' style='font-size: 18.00px; font-family: serif;' textLength='64.48px' lengthAdjust='spacingAndGlyphs'>Serif text</text></g>
</svg>
Maybe I am missing something really obvious, but there just doesn't seem to be any definition happening of the font-family going on. I get identical results on Windows and Linux installations
devtools::session_info()
- Session info ---------------------------------------------------------------------------------------------------
setting value
version R version 3.5.2 (2018-12-20)
os Windows >= 8 x64
system x86_64, mingw32
ui RStudio
language (EN)
collate English_New Zealand.1252
ctype English_New Zealand.1252
tz Australia/Sydney
date 2019-04-07
- Packages -------------------------------------------------------------------------------------------------------
package * version date lib source
assertthat 0.2.0 2017-04-11 [1] CRAN (R 3.5.0)
backports 1.1.3 2018-12-14 [1] CRAN (R 3.5.2)
callr 3.1.1 2018-12-21 [1] CRAN (R 3.5.2)
cli 1.0.1 2018-09-25 [1] CRAN (R 3.5.1)
crayon 1.3.4 2017-09-16 [1] CRAN (R 3.5.0)
desc 1.2.0 2018-05-01 [1] CRAN (R 3.5.0)
devtools 2.0.1 2018-10-26 [1] CRAN (R 3.5.1)
digest 0.6.18 2018-10-10 [1] CRAN (R 3.5.1)
extrafont * 0.17 2014-12-08 [1] CRAN (R 3.5.0)
extrafontdb 1.0 2012-06-11 [1] CRAN (R 3.5.0)
fontBitstreamVera 0.1.1 2017-02-01 [1] CRAN (R 3.5.2)
fontLiberation 0.1.0 2016-10-15 [1] CRAN (R 3.5.2)
fontquiver * 0.2.1 2017-02-01 [1] CRAN (R 3.5.3)
fs 1.2.6 2018-08-23 [1] CRAN (R 3.5.1)
gdtools * 0.1.7 2018-02-27 [1] CRAN (R 3.5.1)
glue 1.3.0 2018-07-17 [1] CRAN (R 3.5.1)
magrittr 1.5 2014-11-22 [1] CRAN (R 3.5.0)
memoise 1.1.0 2017-04-21 [1] CRAN (R 3.5.0)
pkgbuild 1.0.2 2018-10-16 [1] CRAN (R 3.5.1)
pkgload 1.0.2 2018-10-29 [1] CRAN (R 3.5.1)
prettyunits 1.0.2 2015-07-13 [1] CRAN (R 3.5.0)
processx 3.2.1 2018-12-05 [1] CRAN (R 3.5.2)
ps 1.3.0 2018-12-21 [1] CRAN (R 3.5.2)
R6 2.4.0 2019-02-14 [1] CRAN (R 3.5.2)
Rcpp 1.0.0 2018-11-07 [1] CRAN (R 3.5.1)
remotes 2.0.2 2018-10-30 [1] CRAN (R 3.5.1)
rlang 0.3.1 2019-01-08 [1] CRAN (R 3.5.2)
rprojroot 1.3-2 2018-01-03 [1] CRAN (R 3.5.0)
rstudioapi 0.9.0 2019-01-09 [1] CRAN (R 3.5.2)
Rttf2pt1 1.3.7 2018-06-29 [1] CRAN (R 3.5.0)
sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 3.5.1)
svglite * 1.2.1 2017-09-11 [1] CRAN (R 3.5.2)
testthat 2.0.1 2018-10-13 [1] CRAN (R 3.5.1)
usethis 1.4.0 2018-08-14 [1] CRAN (R 3.5.1)
withr 2.1.2 2018-03-15 [1] CRAN (R 3.5.0)
yaml 2.2.0 2018-07-25 [1] CRAN (R 3.5.1)
[1] D:/Peter/Documents/R/win-library/3.5
[2] C:/Program Files/R/R-3.5.2/library
or:
> devtools::session_info()
─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────
setting value
version R version 3.5.1 (2018-07-02)
os Amazon Linux 2
system x86_64, linux-gnu
ui RStudio
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz UTC
date 2019-04-07
─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────
package * version date lib source
assertthat 0.2.0 2017-04-11 [2] CRAN (R 3.5.0)
backports 1.1.2 2017-12-13 [2] CRAN (R 3.5.0)
base64enc 0.1-3 2015-07-28 [2] CRAN (R 3.5.0)
callr 3.0.0 2018-08-24 [2] CRAN (R 3.5.1)
cli 1.0.1 2018-09-25 [2] CRAN (R 3.5.1)
crayon 1.3.4 2017-09-16 [2] CRAN (R 3.5.0)
debugme 1.1.0 2017-10-22 [2] CRAN (R 3.5.0)
desc 1.2.0 2018-05-01 [2] CRAN (R 3.5.0)
devtools 2.0.1 2018-10-26 [2] CRAN (R 3.5.1)
digest 0.6.18 2018-10-10 [2] CRAN (R 3.5.1)
fontBitstreamVera 0.1.1 2017-02-01 [1] CRAN (R 3.5.1)
fontLiberation 0.1.0 2016-10-15 [1] CRAN (R 3.5.1)
fontquiver 0.2.1 2017-02-01 [1] CRAN (R 3.5.1)
fs 1.2.6 2018-08-23 [2] CRAN (R 3.5.1)
gdtools * 0.1.8 2019-04-02 [1] CRAN (R 3.5.1)
glue 1.3.0 2018-07-17 [2] CRAN (R 3.5.1)
magrittr 1.5 2014-11-22 [2] CRAN (R 3.5.0)
memoise 1.1.0 2017-04-21 [2] CRAN (R 3.5.0)
pkgbuild 1.0.2 2018-10-16 [2] CRAN (R 3.5.1)
pkgload 1.0.1 2018-10-11 [2] CRAN (R 3.5.1)
prettyunits 1.0.2 2015-07-13 [2] CRAN (R 3.5.0)
processx 3.2.0 2018-08-16 [2] CRAN (R 3.5.1)
ps 1.2.0 2018-10-16 [2] CRAN (R 3.5.1)
R6 2.3.0 2018-10-04 [2] CRAN (R 3.5.1)
Rcpp 0.12.19 2018-10-01 [2] CRAN (R 3.5.1)
remotes 2.0.1 2018-10-19 [2] CRAN (R 3.5.1)
rlang 0.3.0.1 2018-10-25 [2] CRAN (R 3.5.1)
rprojroot 1.3-2 2018-01-03 [2] CRAN (R 3.5.0)
rstudioapi 0.8 2018-10-02 [2] CRAN (R 3.5.1)
sessioninfo 1.1.0 2018-09-25 [2] CRAN (R 3.5.1)
svglite * 1.2.1 2017-09-11 [1] CRAN (R 3.5.1)
testthat 2.0.1 2018-10-13 [2] CRAN (R 3.5.1)
usethis 1.4.0 2018-08-14 [2] CRAN (R 3.5.1)
withr 2.1.2 2018-03-15 [2] CRAN (R 3.5.0)
yaml 2.2.0 2018-07-25 [2] CRAN (R 3.5.1)
[1] /home/ellisp/R/x86_64-redhat-linux-gnu-library/3.5
[2] /usr/lib64/R/library
[3] /usr/share/R/library
It looks like it works if you use:
lib_fonts <- list(
serif = fontquiver::font_faces("Liberation", "serif")
)
But I don't remember much about all this. It's quite possible the documentation needs to be updated!
Note that the font must be installed on all computers that will view the SVG. If that's for a website, you might need to define CSS font-faces to pluck webfonts from a remote source.
Ah it also work if you specify the name in this way:
lib_fonts <- list(
sans = list(
plain = some_file,
italic = other_file
),
serif = list(plain = list(name = "MY CUSTOM NAME", file = serif_file))
)
There is information about the font family / name in the font file that we may be able to use to infer the name: system2("fc-scan", serif_file)
. We don't currently have the resources to work on svglite though.
Thanks. I opted to make the SVG import the font itself - http://freerangestats.info/blog/2019/04/07/fonts-and-stuff - by hacking the svg file after it's been created.
Not sure if this fits into the svglite philosophy. Would it be worthwhile me trying to make something consistent with the overall svglite approach and submitting a pull request? (not promising I can get to it, but maybe...).
Note that you still need to supply the fonts to svglite in any case, so the textbox metrics can be computed properly.
Would it be worthwhile me trying to make something consistent with the overall svglite approach and submitting a pull request?
If you think you have a better approach that fits (or updates) current svglite tooling and follows best web dev practices, please go for it! Happy to review a PR.