wch / extrafont

Tools for using fonts in R graphics
313 stars 49 forks source link

How to use extrafont in a package? #44

Open wangyuchen opened 8 years ago

wangyuchen commented 8 years ago

I'm writing a package where I would like to include some plotting functions with a specified font.

I added extrafont to the imports field in DESCRIPTION, and use extrafont::choose_font() to choose a font from several options. However, I have to attach extrafont package manually to get the font to work.

I noticed that extrafont use .onAttach() to register fonts, and by default packages in imports will be loaded but not attached. So when I load my package, .onAttach() will not run, right? Is there any way to get around this without adding it to the depends field? Thanks.

wch commented 8 years ago

Hm... For your package to work, you can:

wangyuchen commented 8 years ago

Thanks!

It seems like the first two options are not usually recommended, so I decided I should add the loadfonts() to somewhere in my package.

I tried adding it to the function that need to use fonts, but it seems strange it will load fonts while what I really want is to use some fonts. Also, it will generate warnings when I check() the package because I guess when checking, the function doesn't run.

Then I tried add it to my own .onAttach(), it worked fine, but when I check package, the check failed when loading NAMESPACE with the following error:

Error : .onAttach failed in attachNamespace() for 'alt005', details:
  call: get(as.character(FUN), mode = "function", envir = envir)
  error: object 'pdfFonts' of mode 'function' was not found
Error: package or namespace load failed for 'alt005'
Execution halted

Should I try adding it to other places or should I just use require(extrafont)?

ampu3ro commented 7 years ago

I just ran into this issue as well. I believe it happens because loadfonts() calls pdfFonts() postscriptFonts() or windowsFonts() without specifying that they come from the grDevices package environment. Until it's modified internally, you can specify the function explicitly like

.onLoad <- function(libname,pkgname) {
  pdfFonts <- grDevices::pdfFonts
  extrafont::loadfonts("pdf",quiet=T)
}

Alternatively, you could require(grDevices) but devtools::check() notes that you shouldn't

JanaJarecki commented 5 years ago

Hi guys, is there any update on this issue? I have trouble inserting the initialization of a font into the .onLoad() function of my package. best Jana

petrbouchal commented 4 years ago

FWIW I ended up doing the below, with extrafont in Imports - overall it is an adaptation of the code in hrbrthemes, with added *Fonts <- grDevices::*Fonts calls for each "missing" function.

It now passed the Windows and Mac checks on r-hub without warnings, and likewise for the MacOS on my Mac (the Fedora and Linux rhub builds fails because of errors in building other dependencies). Without the additions, the package fails to load during Windows rhub check, returning the error reported by @wangyuchen.

I still don't know what I am missing given that e.g. hrbrthemes passes CRAN checks without the extra grDevices lines...

.onAttach <- function(libname, pkgname) {

  # adapted from hrbrthemes

  # Suggestion by @alexwhan

  if (.Platform$OS.type == "windows")  { # nocov start
    # fix as per https://github.com/wch/extrafont/issues/44#issue-comment-box
    windowsFonts <- grDevices::windowsFonts
    if (interactive()) packageStartupMessage("Registering Windows fonts with R")
    extrafont::loadfonts("win", quiet = TRUE)
  }

  if (getOption("reschola.loadfonts", default = FALSE)) {
    if (interactive()) packageStartupMessage("Registering PDF & PostScript fonts with R")
    # fix as per https://github.com/wch/extrafont/issues/44#issue-comment-box
    pdfFonts <- grDevices::pdfFonts
    postscriptFonts <- grDevices::postscriptFonts
    extrafont::loadfonts("pdf", quiet = TRUE)
    extrafont::loadfonts("postscript", quiet = TRUE)
  }

  fnt <- extrafont::fonttable()
  if (!any(grepl("Roboto|Roboto[ ]Condensed", fnt$FamilyName))) {
    packageStartupMessage("NOTE: Roboto and Roboto Condensed fonts are required for the default setting of theme_schola() to work.")
    packageStartupMessage("      Please use reschola::import_fonts() to install Roboto and Roboto Condensed")
  } # nocov end

}