# Font family name constants used as defaults in theme functions. # These match the --cv-font-* CSS custom properties on www.civilytics.com. CV_FONT_DISPLAY <- "Libre Franklin" # headings / display text CV_FONT_SANS <- "Inter" # axis text, legends, UI elements CV_FONT_SERIF <- "Source Serif 4" # body prose / editorial long-form CV_FONT_MONO <- "JetBrains Mono" # code, data tables, numeric callouts # Mutable package state held in an environment so the binding itself stays # locked (R locks all namespace bindings at load time) while the contents # remain writable. See https://adv-r.hadley.nz/environments.html#environments-as-containers .cv_state <- new.env(parent = emptyenv()) .cv_state$fonts_loaded <- FALSE #' Load Civilytics brand fonts #' #' Downloads Inter, Libre Franklin, Source Serif 4 and JetBrains Mono from #' Google Fonts via [sysfonts::font_add_google()], then calls #' [showtext::showtext_auto()] so that all graphics devices render text with #' those fonts. This is called automatically when the package loads; use this #' function to retry if the initial load failed (e.g., the machine was offline #' at load time). #' #' Subsequent calls within the same session are no-ops unless `force = TRUE`. #' #' @param force Logical. If `TRUE`, reload fonts even if they were already #' loaded in this session. Default `FALSE`. #' #' @return Invisibly returns `TRUE` if fonts were loaded, `FALSE` if skipped #' (already loaded and `force = FALSE`). #' @export #' #' @examples #' \dontrun{ #' civilytics_load_fonts() #' } civilytics_load_fonts <- function(force = FALSE) { if (.cv_state$fonts_loaded && !force) return(invisible(FALSE)) sysfonts::font_add_google("Inter", family = "Inter") sysfonts::font_add_google("Libre Franklin", family = "Libre Franklin") sysfonts::font_add_google("Source Serif 4", family = "Source Serif 4") sysfonts::font_add_google("JetBrains Mono", family = "JetBrains Mono") showtext::showtext_auto() .cv_state$fonts_loaded <- TRUE invisible(TRUE) } .onLoad <- function(libname, pkgname) { tryCatch( civilytics_load_fonts(), error = function(e) { # Store the failure so .onAttach can surface a message to the user. options(.civilytics_fonts_failed = TRUE) } ) } .onAttach <- function(libname, pkgname) { if (isTRUE(getOption(".civilytics_fonts_failed"))) { packageStartupMessage( "[civilytics] Brand fonts (Inter, Libre Franklin, Source Serif 4, ", "JetBrains Mono) could not be loaded from Google Fonts. ", "Charts will fall back to system fonts. ", "Call civilytics_load_fonts() once you have an internet connection." ) } }