rggplot2fontsextrafont

How can I check whether a given font has been loaded already using extrafont package in R?


I've written a function to share among colleagues for graphing, and my organization prefers Calibri to the ggplot2 default Arial for the text. If I were the only person who'd be using this function, I would first do this at the top of my script:

 library(extrafont)
 font_import()
 loadfonts(device="win")

and then make my ggplot2 graph. I seem to only have to do font_import() once on a given machine, but then I need to do loadfonts(device="win") each time I start a new session. I'm not terribly well versed in what these do, but if I don't do the loadfonts step, my graph doesn't use Calibri.

I'd like the graphing function I wrote to work for others, and I'd like to check whether they've already done these steps and give them a helpful message about it if they haven't. I thought I could use fonts() and then check whether Calibri was listed in the output, but I think that only checks what fonts I've ever loaded with font_import() in the history of using this machine. I also thought maybe

 systemfonts::match_font("Calibri")

would check, but I get the same result regardless of whether I've already run loadfonts(..., so that's not it, either.

How do you check whether a font is ready to be used in a graph?


Solution

  • Here is one potential approach to determine whether Calibri is installed and 'useable':

    install.packages("showtext")
    library(showtext)
    list_of_fonts <- as.data.frame(font_files())
    
    grep(pattern = "Calibri", x = list_of_fonts$family, ignore.case = TRUE, value = TRUE)
    

    You can implement this in a number of ways, e.g. load the Calibri font if it's available or print a message if it's not available on the system:

    if (!require(showtext)) install.packages("showtext")
    #> Loading required package: showtext
    #> Loading required package: sysfonts
    #> Loading required package: showtextdb
    library(showtext)
    list_of_fonts <- as.data.frame(font_files())
    if(any(grepl("Calibri.ttf", list_of_fonts, ignore.case = TRUE))){
      Calibri <- list_of_fonts[list_of_fonts$file == "Calibri.ttf",]
      sysfonts::font_add(family = "Calibri",
                         regular = list.files(path = Calibri$path,
                                              pattern = "Calibri.ttf",
                                              full.names = TRUE))
      print("Calibri available")
    } else{
      print("Calibri not found")
    }
    #> [1] "Calibri available"
    
    library(ggplot2)
    showtext_auto()
    ggplot(mtcars, aes(wt, mpg)) +
      geom_point() +
      ggtitle("Example plot") +
      theme(text = element_text(family = "Calibri", size = 22))
    

    Created on 2021-09-29 by the reprex package (v2.0.1)

    N.B. This should work on windows/macOS/linux but I've only tested it on macOS. Also, @JonSpring commented first, so if he posts an answer please accept his instead of mine