├── .Rbuildignore ├── .gitignore ├── .travis.yml ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS.md ├── R ├── font-getters.R ├── fontset-bitstream-vera.R ├── fontset-dejavu.R ├── fontset-liberation.R ├── fontset-symbola.R ├── fontset.R ├── html-dependency.R └── utils.R ├── README.md ├── cran-comments.md ├── fontquiver.Rproj ├── inst └── fonts │ ├── symbola-VERSION │ └── symbola-fonts │ ├── Symbola.ttf │ └── Symbola.woff ├── man ├── font_families.Rd ├── font_variants.Rd ├── fonts.Rd ├── fontset_info.Rd ├── fontset_list.Rd ├── fontset_register.Rd ├── fontset_variants.Rd ├── htmlFontDependency.Rd └── splice_fonts.Rd └── tests ├── testthat.R └── testthat ├── test-fonts.R └── test-html-dependency.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^\.travis\.yml$ 4 | ^cran-comments\.md$ 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # R for travis: see documentation at https://docs.travis-ci.com/user/languages/r 2 | 3 | language: R 4 | sudo: false 5 | cache: packages 6 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: fontquiver 2 | Title: Set of Installed Fonts 3 | Version: 0.2.1 4 | Authors@R: c( 5 | person("Lionel", "Henry", , "lionel@rstudio.com", c("cre", "aut")), 6 | person("RStudio", role = "cph"), 7 | person("George Douros", role = "cph", comment = "Symbola font")) 8 | Description: Provides a set of fonts with permissive licences. This is 9 | useful when you want to avoid system fonts to make sure your 10 | outputs are reproducible. 11 | Depends: 12 | R (>= 3.0.0) 13 | Imports: 14 | fontBitstreamVera (>= 0.1.0), 15 | fontLiberation (>= 0.1.0) 16 | Suggests: 17 | testthat, 18 | htmltools 19 | License: GPL-3 | file LICENSE 20 | Encoding: UTF-8 21 | LazyData: true 22 | RoxygenNote: 5.0.1 23 | Collate: 24 | 'font-getters.R' 25 | 'fontset.R' 26 | 'fontset-bitstream-vera.R' 27 | 'fontset-dejavu.R' 28 | 'fontset-liberation.R' 29 | 'fontset-symbola.R' 30 | 'html-dependency.R' 31 | 'utils.R' 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Fontquiver as a whole is released under GPL-3. It includes the Symbola 2 | font which is GPL-3 compatible. 3 | 4 | 5 | Symbola 6 | ------- 7 | 8 | Copyright (C) 2007-2016 George Douros 9 | 10 | Fonts are free for any use; they may be opened, edited, modified, 11 | regenerated, packaged and redistributed. 12 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(font) 4 | export(font_faces) 5 | export(font_families) 6 | export(font_styles) 7 | export(font_symbol) 8 | export(font_variants) 9 | export(fonts) 10 | export(fontset_info) 11 | export(fontset_list) 12 | export(fontset_register) 13 | export(fontset_styles) 14 | export(fontset_variants) 15 | export(htmlFontDependency) 16 | export(splice_fonts) 17 | import(fontBitstreamVera) 18 | import(fontLiberation) 19 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # fontquiver 0.2.x (unreleased) 2 | 3 | - Fix warnings in non-UTF-8 MBCS locale (#9, @yutannihilation). 4 | 5 | 6 | # fontquiver 0.2.1 7 | 8 | - Set minimum R version to 3.0.0. 9 | 10 | 11 | # fontquiver 0.2.0 12 | 13 | - Add Liberation and Symbola fonts 14 | 15 | - Removed `font_bitstream_vera()` and `font_dejavu()` getters. They 16 | are replaced by a family of generic font getters: `font()` to 17 | retrieve the font for a given variant and style, and `fonts()` to 18 | retieve all fonts defined in a fontset. 19 | 20 | - Add `font_families()` and `font_faces()` to retrieve font files 21 | organised according to R's nomenclature of fonts. Conversely there is 22 | now `font_variants()` and `font_styles()` which organise fonts 23 | according to fontconfig's categories. Also, `font_symbol()` 24 | allows to retrieve a symbol font defined by a fontset (currently 25 | only the Symbola fontset defines one). 26 | 27 | - `htmlFontDependency()` now takes fonts and collections of fonts (as 28 | returned by `font_families()` and friends) as argument. 29 | 30 | - `htmlFontDependency()` now uses the style-linking idiom for 31 | generating CSS. 32 | 33 | 34 | # fontquiver 0.1.0 35 | 36 | Initial release 37 | 38 | - Add `font_bitstream_vera()` and `font_dejavu()`. The latter require 39 | installing the fontDejaVu package from Github: 40 | `devtools::install_github("lionel-/fontDejaVu")`. 41 | 42 | - Implement `htmlFontDependency()` to include font dependency in web 43 | pages or applications. 44 | -------------------------------------------------------------------------------- /R/font-getters.R: -------------------------------------------------------------------------------- 1 | #' Get elements of a fontset 2 | #' 3 | #' \code{fonts()} returns the list of all \code{font} objects for a 4 | #' given fontset (a collection of fonts provided by fontquiver, such 5 | #' as \code{Liberation} or \code{Bitstream Vera}). \code{font()} 6 | #' returns one specific font. \code{font_symbol()} extracts the font 7 | #' marked as symbol font, if it exists in the fontset. 8 | #' @inheritParams fontset_info 9 | #' @param variant Font variant, as per Fontconfig's nomenclature. Use 10 | #' \code{\link{fontset_variants}()} to find out which variants are 11 | #' available for a fontset. 12 | #' @param style Font style, as per Fontconfig's nomenclature. Use 13 | #' \code{\link{fontset_styles}()} to find out which variants are 14 | #' available for a fontset. 15 | #' @export 16 | #' @examples 17 | #' font("Bitstream Vera", "Sans", "Roman") 18 | #' 19 | #' f <- fonts("Liberation") 20 | #' str(f, 1) 21 | #' 22 | #' font_symbol("Symbola") 23 | fonts <- function(fontset) { 24 | info <- fontset_info(fontset) 25 | getter <- fontset_props(fontset)$getter 26 | 27 | fonts <- Map(getter, variant = info$variant, style = info$style) 28 | fonts_names <- flatten(Map(paste, info$variant, style = info$style, sep = "-")) 29 | names(fonts) <- vapply_chr(fonts_names, str_prettify) 30 | 31 | fonts 32 | } 33 | 34 | #' @rdname fonts 35 | #' @export 36 | font <- function(fontset, variant, style) { 37 | fontset_props(fontset)$getter(variant, style) 38 | } 39 | 40 | #' @rdname fonts 41 | #' @export 42 | font_symbol <- function(fontset = "Symbola") { 43 | families <- font_families(fontset) 44 | families$symbol$symbol 45 | } 46 | 47 | #' Font families and faces 48 | #' 49 | #' Returns families or faces as font files for a given font set. The 50 | #' files are organised by R nomenclature of families (\code{"sans"}, 51 | #' \code{"serif"}, \code{"mono"}, and \code{"symbol"}) and faces 52 | #' (\code{"plain"}, \code{"italic"}, \code{"bold"}, and 53 | #' \code{"bolditalic"}). When a font does not have a combination, 54 | #' \code{NA} is reported. 55 | #' 56 | #' Note that the fonts returned by \code{font_faces()} and 57 | #' \code{\link{font_families}()} are constrained by R's nomenclature 58 | #' of fonts and are thus a subset of those returned by 59 | #' \code{\link{font_variants}()} and \code{\link{font_styles}()}. 60 | #' @inheritParams fontset_info 61 | #' @param family One of \code{"sans"}, \code{"serif"}, \code{"mono"} 62 | #' or \code{"symbol"}. 63 | #' @export 64 | #' @seealso \code{\link{font_variants}()}, \code{\link{fonts}()} 65 | #' @examples 66 | #' font_families("Bitstream Vera")$mono$bold 67 | #' font_faces("Bitstream Vera", "mono") 68 | font_families <- function(fontset) { 69 | info <- fontset_info(fontset) 70 | props <- fontset_props(fontset) 71 | getter <- props$getter 72 | 73 | filter_file <- function(...) { 74 | filtered <- filter_first(info, ..., ~!is.na(family), ~!is.na(face)) 75 | if (nrow(filtered)) { 76 | do.call(getter, filtered[c("variant", "style")]) 77 | } else { 78 | NULL 79 | } 80 | } 81 | 82 | fnames <- set_names(c("sans", "serif", "mono", "symbol")) 83 | families <- lapply(fnames, function(r_family) { 84 | family <- list( 85 | plain = filter_file(~family == r_family, ~face == "plain"), 86 | italic = filter_file(~family == r_family, ~face == "italic"), 87 | bold = filter_file(~family == r_family, ~face == "bold"), 88 | bolditalic = filter_file(~family == r_family, ~face == "bolditalic"), 89 | symbol = filter_file(~family == r_family, ~face == "symbol") 90 | ) 91 | structure(family, class = "font_faces") 92 | }) 93 | 94 | structure(families, class = "font_families") 95 | } 96 | 97 | #' @rdname font_families 98 | #' @export 99 | font_faces <- function(fontset, family = c("sans", "serif", "mono", "symbol")) { 100 | choices <- c("sans", "serif", "mono", "symbol") 101 | family <- match.arg(str_standardise(family), choices) 102 | families <- font_families(fontset) 103 | families[[family]] 104 | } 105 | 106 | #' Font variants 107 | #' 108 | #' \code{font_variants()} returns a tree of fonts organised as per 109 | #' fontconfig's nomenclature. The first level contains variants of a 110 | #' font and the second level contains font styles. 111 | #' 112 | #' See also \code{\link{font_families}()} and \code{\link{font_faces}()} 113 | #' for similar collections organised according to R nomenclature of 114 | #' fonts. Note that variants and styles are a super set of R families 115 | #' and faces and may contain more fonts. 116 | #' 117 | #' @inheritParams font 118 | #' @seealso \code{\link{font_families}()}, \code{\link{fonts}()} 119 | #' @export 120 | #' @examples 121 | #' font_variants("Bitstream Vera") 122 | #' font_variants("Bitstream Vera")$Sans$Oblique 123 | #' font_styles("Bitstream Vera", "Sans") 124 | font_variants <- function(fontset) { 125 | props <- fontset_props(fontset) 126 | names(props$files) <- str_prettify(names(props$files)) 127 | 128 | variants <- Map(function(variant, variant_name) { 129 | styles <- set_names(str_prettify(names(variant))) 130 | styles <- lapply(styles, props$getter, variant = variant_name) 131 | structure(styles, class = "font_styles") 132 | }, props$files, names(props$files)) 133 | 134 | structure(variants, class = "font_variants") 135 | } 136 | 137 | #' @rdname font_variants 138 | #' @export 139 | font_styles <- function(fontset, variant) { 140 | variant <- str_prettify(variant) 141 | variants <- font_variants(fontset) 142 | variants[[variant]] 143 | } 144 | -------------------------------------------------------------------------------- /R/fontset-bitstream-vera.R: -------------------------------------------------------------------------------- 1 | #' @references \url{https://www.gnome.org/fonts/} 2 | #' @import fontBitstreamVera 3 | #' @include fontset.R 4 | fontset_bitstream_vera <- function(variant = "sans", style = "roman") { 5 | font_get("Bitstream Vera", variant, style, pkg = "fontBitstreamVera") 6 | } 7 | 8 | fontset_bitstream_vera_files <- list( 9 | sans = list( 10 | roman = sans("Vera", face = "plain", weight = 80), 11 | oblique = sans("VeraIt", face = "italic", weight = 80), 12 | bold = sans("VeraBd", face = "bold", weight = 200), 13 | `bold-oblique` = sans("VeraBI", face = "bolditalic", weight = 200) 14 | ), 15 | `sans-mono` = list( 16 | roman = mono("VeraMono", face = "plain", weight = 80), 17 | oblique = mono("VeraMoIt", face = "italic", weight = 80), 18 | bold = mono("VeraMoBd", face = "bold", weight = 200), 19 | `bold-oblique` = mono("VeraMoBI", face = "bolditalic", weight = 200) 20 | ), 21 | serif = list( 22 | roman = serif("VeraSe", face = "plain", weight = 80), 23 | bold = serif("VeraSeBd", face = "bold", weight = 200) 24 | ) 25 | ) 26 | 27 | fontset_register("Bitstream Vera", 28 | getter = fontset_bitstream_vera, 29 | files = fontset_bitstream_vera_files 30 | ) 31 | -------------------------------------------------------------------------------- /R/fontset-dejavu.R: -------------------------------------------------------------------------------- 1 | #' @references \url{http://dejavu-fonts.org} 2 | #' @include fontset.R 3 | fontset_dejavu <- function(variant = "sans", style = "book") { 4 | if (system.file("fonts", package = "fontDejaVu") == "") { 5 | stop(call. = FALSE, 6 | "fontDejaVu must be installed from Github. Please run:\n", 7 | " install.packages('devtools')\n", 8 | " devtools::install_github('lionel-/fontDejaVu')" 9 | ) 10 | } 11 | font_get("DejaVu", variant, style, pkg = "fontDejaVu") 12 | } 13 | 14 | fontset_dejavu_files <- list( 15 | sans = list( 16 | book = sans("ttf/DejaVuSans", face = "plain", weight = 80), 17 | oblique = sans("ttf/DejaVuSans-Oblique", face = "italic", weight = 80), 18 | bold = sans("ttf/DejaVuSans-Bold", face = "bold", weight = 200), 19 | `bold-oblique` = sans("ttf/DejaVuSans-BoldOblique", face = "bolditalic", weight = 200), 20 | `extra-light` = sans("ttf/DejaVuSans-ExtraLight", weight = 40) 21 | ), 22 | `sans-condensed` = list( 23 | book = other("ttf/DejaVuSansCondensed", face = "plain", weight = 80), 24 | oblique = other("ttf/DejaVuSansCondensed-Oblique", face = "italic", weight = 80), 25 | bold = other("ttf/DejaVuSansCondensed-Bold", face = "bold", weight = 200), 26 | `bold-oblique` = other("ttf/DejaVuSansCondensed-BoldOblique", face = "bolditalic", weight = 200) 27 | ), 28 | `sans-mono` = list( 29 | book = mono("ttf/DejaVuSansMono", face = "plain", weight = 80), 30 | oblique = mono("ttf/DejaVuSansMono-Oblique", face = "italic", weight = 80), 31 | bold = mono("ttf/DejaVuSansMono-Bold", face = "bold", weight = 200), 32 | `bold-oblique` = mono("ttf/DejaVuSansMono-BoldOblique", face = "bolditalic", weight = 200) 33 | ), 34 | serif = list( 35 | book = serif("ttf/DejaVuSerif", face = "plain", weight = 80), 36 | italic = serif("ttf/DejaVuSerif-Italic", face = "italic", weight = 80), 37 | bold = serif("ttf/DejaVuSerif-Bold", face = "bold", weight = 200), 38 | `bold-italic` = serif("ttf/DejaVuSerif-BoldItalic", face = "bolditalic", weight = 200) 39 | ), 40 | `serif-condensed` = list( 41 | book = other("ttf/DejaVuSerifCondensed", face = "plain", weight = 80), 42 | italic = other("ttf/DejaVuSerifCondensed-Italic", face = "italic", weight = 80), 43 | bold = other("ttf/DejaVuSerifCondensed-Bold", face = "bold", weight = 200), 44 | `bold-italic` = other("ttf/DejaVuSerifCondensed-BoldItalic", face = "bolditalic", weight = 200) 45 | ), 46 | `math-tex-gyre` = list( 47 | regular = other("ttf/DejaVuMathTexGyre", face = "plain", weight = 80) 48 | ) 49 | ) 50 | 51 | fontset_register("DejaVu", 52 | getter = fontset_dejavu, 53 | files = fontset_dejavu_files 54 | ) 55 | -------------------------------------------------------------------------------- /R/fontset-liberation.R: -------------------------------------------------------------------------------- 1 | #' @references \url{https://fedorahosted.org/liberation-fonts/} 2 | #' @import fontLiberation 3 | #' @include fontset.R 4 | fontset_liberation <- function(variant = "sans", style = "regular") { 5 | font_get("Liberation", variant, style, pkg = "fontLiberation") 6 | } 7 | 8 | fontset_liberation_files <- list( 9 | sans = list( 10 | regular = sans("LiberationSans-Regular", face = "plain", weight = 80), 11 | italic = sans("LiberationSans-Italic", face = "italic", weight = 80), 12 | bold = sans("LiberationSans-Bold", face = "bold", weight = 200), 13 | `bold-italic` = sans("LiberationSans-BoldItalic", face = "bolditalic", weight = 200) 14 | ), 15 | `mono` = list( 16 | regular = mono("LiberationMono-Regular", face = "plain", weight = 80), 17 | oblique = mono("LiberationMono-Italic", face = "italic", weight = 80), 18 | bold = mono("LiberationMono-Bold", face = "bold", weight = 200), 19 | `bold-italic` = mono("LiberationMono-BoldItalic", face = "bolditalic", weight = 200) 20 | ), 21 | serif = list( 22 | regular = serif("LiberationSerif-Regular", face = "plain", weight = 80), 23 | italic = serif("LiberationSerif-Italic", face = "italic", weight = 80), 24 | bold = serif("LiberationSerif-Bold", face = "bold", weight = 200), 25 | `bold-italic` = serif("LiberationSerif-BoldItalic", face = "bolditalic", weight = 200) 26 | ) 27 | ) 28 | 29 | fontset_register("Liberation", 30 | getter = fontset_liberation, 31 | files = fontset_liberation_files 32 | ) 33 | -------------------------------------------------------------------------------- /R/fontset-symbola.R: -------------------------------------------------------------------------------- 1 | #' @references \url{http://users.teilar.gr/~g1951d/} 2 | #' @include fontset.R 3 | fontset_symbola <- function(variant = "symbols", style = "regular") { 4 | font <- font_get("Symbola", variant, style, pkg = "fontquiver") 5 | font$name <- "Symbola" 6 | font$fullname <- "Symbola" 7 | font 8 | } 9 | 10 | fontset_symbola_files <- list( 11 | symbols = list( 12 | regular = symbol("Symbola", face = "symbol", weight = 80) 13 | ) 14 | ) 15 | 16 | fontset_register("Symbola", 17 | getter = fontset_symbola, 18 | files = fontset_symbola_files 19 | ) 20 | -------------------------------------------------------------------------------- /R/fontset.R: -------------------------------------------------------------------------------- 1 | #' Fontset metadata 2 | #' 3 | #' This returns a data frame containing metadata about fonts. The 4 | #' columns "variant" and "style" correspond to the properties of the 5 | #' font as reported by fontconfig. The columns "family", "italic" and 6 | #' "bold" provide information in terms of R nomenclature of fonts. The 7 | #' column "base" gives the base filename of the font. See 8 | #' \code{\link{fontset_list}()} to obtain a list of available 9 | #' fontsets. 10 | #' 11 | #' @param fontset A string giving the name of a set of fonts 12 | #' (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 13 | #' \code{\link{fontset_list}()} to obtain the list of fontsets 14 | #' registered in your session. 15 | #' @seealso \code{\link{fontset_list}()}, \code{\link{font_families}()}, 16 | #' \code{\link{font_variants}()} 17 | #' @export 18 | fontset_info <- function(fontset) { 19 | props <- fontset_props(fontset) 20 | info <- at_bottom(props$files, spread_attributes, "base") 21 | gather_tree(info, c("variant", "style")) 22 | } 23 | 24 | #' Fontset variants and styles 25 | #' 26 | #' These functions return the variants and the styles available for a 27 | #' given fontset. 28 | #' @inheritParams fonts 29 | #' @export 30 | #' @examples 31 | #' fontset_variants("Liberation") 32 | #' fontset_styles("Bitstream Vera", "Sans Mono") 33 | fontset_variants <- function(fontset) { 34 | props <- fontset_props(fontset) 35 | str_prettify(names(props$files)) 36 | } 37 | 38 | #' @rdname fontset_variants 39 | #' @export 40 | fontset_styles <- function(fontset, variant) { 41 | props <- fontset_props(fontset) 42 | variant <- str_standardise(variant) 43 | str_prettify(names(props$files[[variant]])) 44 | } 45 | 46 | registered_fontsets <- new.env(parent = emptyenv()) 47 | 48 | #' Register a font to fontquiver 49 | #' 50 | #' @param fontset Name of the font set. 51 | #' @param getter Constructor of \code{font} objects. 52 | #' @param files Data structure containing font information. 53 | #' @export 54 | fontset_register <- function(fontset, getter, files) { 55 | props <- list(getter = getter, files = files) 56 | assign(fontset, props, envir = registered_fontsets) 57 | } 58 | 59 | #' Get list of all registered fonts 60 | #' 61 | #' @export 62 | fontset_list <- function() { 63 | names(registered_fontsets) 64 | } 65 | 66 | fontset_props <- function(fontset) { 67 | fontset <- str_prettify(fontset) 68 | get(fontset, envir = registered_fontsets) 69 | } 70 | 71 | 72 | # Constructors ------------------------------------------------------- 73 | 74 | font_data <- function(base, family, face, weight) { 75 | structure(base, 76 | family = family, 77 | face = face, 78 | weight = weight, 79 | class = "font_data" 80 | ) 81 | } 82 | 83 | other <- function(base, face = NA, weight = NA) { 84 | font_data(base, family = NA, face = face, weight = weight) 85 | } 86 | 87 | sans <- function(base, face = NA, weight = NA) { 88 | font_data(base = base, family = "sans", face = face, weight = weight) 89 | } 90 | 91 | serif <- function(base, face = NA, weight = NA) { 92 | font_data(base = base, family = "serif", face = face, weight = weight) 93 | } 94 | 95 | mono <- function(base, face = NA, weight = NA) { 96 | font_data(base = base, family = "mono", face = face, weight = weight) 97 | } 98 | 99 | symbol <- function(base, face = NA, weight = NA) { 100 | font_data(base = base, family = "symbol", face = face, weight = weight) 101 | } 102 | -------------------------------------------------------------------------------- /R/html-dependency.R: -------------------------------------------------------------------------------- 1 | #' Include font as CSS dependency 2 | #' 3 | #' @inheritParams splice_fonts 4 | #' @export 5 | #' @examples 6 | #' # Create an htmlDependency object: 7 | #' dep <- htmlFontDependency(font_families("Bitstream Vera")) 8 | #' 9 | #' # Use the fonts in your dependent css or html files. For example: 10 | #' # body { 11 | #' # font-family: 'Bitstream Vera Sans Mono', courier; 12 | #' # } 13 | htmlFontDependency <- function(...) { 14 | if (!requireNamespace("htmltools")) { 15 | stop("htmltools is not installed", call. = FALSE) 16 | } 17 | fonts <- unique(splice_fonts(...)) 18 | 19 | css_dir <- file.path(tempdir(), "fontquiver") 20 | if (!dir.exists(css_dir)) dir.create(css_dir) 21 | css_file <- tempfile("fontquiver-dep", css_dir, fileext = ".css") 22 | 23 | css <- lapply(fonts, function(font) { 24 | css_font_face(font$name, font$ttf, font$face, font$weight) 25 | }) 26 | css <- flatten(css) 27 | writeLines(css, css_file, useBytes = TRUE) 28 | 29 | lapply(fonts, function(font) { 30 | file.copy(font$woff, file.path(css_dir, basename(font$woff))) 31 | }) 32 | 33 | pkgs <- unique(vapply_chr(fonts, `[[`, "package")) 34 | vers <- unique(vapply_chr(fonts, `[[`, "version")) 35 | 36 | htmltools::htmlDependency( 37 | name = paste(pkgs, collapse = "-"), 38 | version = paste(vers, collapse = "-"), 39 | src = css_dir, 40 | stylesheet = basename(css_file) 41 | ) 42 | } 43 | 44 | css_font_style <- function(face) { 45 | switch(face, 46 | italic = "italic", 47 | bolditalic = "italic", 48 | "normal" 49 | ) 50 | } 51 | 52 | # Loosely adapted from 53 | # https://lists.freedesktop.org/archives/fontconfig/2011-September/003645.html 54 | css_font_weight <- function(w) { 55 | if (w <= 40) return(100) 56 | if (w <= 50) return(200) 57 | if (w <= 70) return(300) 58 | if (w <= 80) return(400) 59 | if (w <= 100) return(500) 60 | if (w <= 180) return(600) 61 | if (w <= 200) return(700) 62 | if (w <= 205) return(800) 63 | 900 64 | } 65 | 66 | # https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face 67 | css_font_face <- function(name, file, style, weight) { 68 | file <- str_trim_ext(basename(file)) 69 | style <- css_font_style(style) 70 | weight <- css_font_weight(weight) 71 | gsub("%s", file, c( 72 | "@font-face {", 73 | sprintf(" font-family: '%s';", name), 74 | sprintf(" font-style: %s;", style), 75 | sprintf(" font-weight: %s;", weight), 76 | " src:", 77 | " url('%s.woff') format('woff');", 78 | "}\n" 79 | )) 80 | } 81 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | 2 | font_get <- function(fontset, variant, style, pkg) { 3 | variant <- str_standardise(variant, sep = "-") 4 | style <- str_standardise(style, sep = "-") 5 | 6 | props <- fontset_props(fontset) 7 | check_font_family(variant, style, props$files) 8 | 9 | std_name <- str_standardise(fontset, sep = "-") 10 | base <- props$files[[variant]][[style]] 11 | ttf <- concat_font(std_name, base, "ttf", package = pkg) 12 | woff <- concat_font(std_name, base, "woff", package = pkg) 13 | version <- font_version(std_name, package = pkg) 14 | name <- paste(fontset, str_prettify(variant), sep = " ") 15 | fullname <- paste(name, str_prettify(style), sep = " ") 16 | 17 | structure(class = "font", list( 18 | ttf = ttf, 19 | woff = woff, 20 | fontset = fontset, 21 | name = name, 22 | fullname = fullname, 23 | variant = variant, 24 | style = style, 25 | weight = attr(base, "weight"), 26 | family = attr(base, "family"), 27 | face = attr(base, "face"), 28 | package = pkg, 29 | version = version 30 | )) 31 | } 32 | 33 | check_font_family <- function(face, style, files) { 34 | face <- str_standardise(face, sep = "-") 35 | style <- str_standardise(style, sep = "-") 36 | 37 | if (!face %in% names(files)) { 38 | stop(call. = FALSE, 39 | "Available variants:\n", 40 | paste(str_prettify(names(files)), collapse = ", ") 41 | ) 42 | } 43 | 44 | if (!style %in% names(files[[face]])) { 45 | styles <- names(files[[face]]) 46 | styles <- paste(str_prettify(styles), collapse = ", ") 47 | stop(call. = FALSE, "Available styles for variant ", face, ":\n", styles) 48 | } 49 | } 50 | 51 | check_font_exists <- function(font, package) { 52 | dir <- system.file("fonts", paste0(font, "-fonts"), package = package) 53 | dir.exists(dir) 54 | } 55 | 56 | concat_font <- function(base, name, ext, package) { 57 | dir <- paste0(base, "-fonts") 58 | filename <- paste(name, ext, sep = ".") 59 | path <- file.path(dir, filename) 60 | 61 | file <- system.file("fonts", path, package = package) 62 | if (file == "") { 63 | stop("Internal error: cannot find font", filename) 64 | } 65 | file 66 | } 67 | 68 | font_version <- function(font, package) { 69 | file <- system.file("fonts", paste0(font, "-VERSION"), package = package) 70 | readChar(file, file.info(file)$size - 1, useBytes = TRUE) 71 | } 72 | 73 | #' Splice fonts and font collections 74 | #' 75 | #' \code{splice_fonts()} Reduces its arguments to a flat list. It 76 | #' accepts indinstinctly \code{font} objects, lists of \code{font} 77 | #' objects (obtained with \code{\link{fonts}()}), or collections of 78 | #' fonts produced by \code{\link{font_variants}()} or 79 | #' \code{\link{font_families}()}. Duplicate fonts are removed from the 80 | #' result. 81 | #' 82 | #' @param ... Fonts or collections of fonts. See 83 | #' \code{\link{font_families}()} and \code{\link{font_variants}()} 84 | #' for creating collections of fonts. You can also supply lists of 85 | #' individual fonts as returned by \code{\link{fonts}()}. 86 | #' @export 87 | #' @examples 88 | #' splice_fonts(font("Bitstream Vera", "Sans", "Oblique"), font_faces("Bitstream Vera", "mono")) 89 | splice_fonts <- function(...) { 90 | fonts <- list(...) 91 | 92 | known_classes <- c( 93 | "font_families", "font_variants","font_faces", 94 | "font_styles", "font", "list" 95 | ) 96 | unknown <- setdiff(vapply_chr(fonts, class), known_classes) 97 | if (length(unknown)) { 98 | stop("Unknown classes: ", paste(unknown, collapse = ", "), call. = FALSE) 99 | } 100 | 101 | meta <- keep(fonts, inherits, c("font_families", "font_variants")) 102 | coll <- keep(fonts, inherits, c("font_faces", "font_styles")) 103 | file <- keep(fonts, inherits, "font") 104 | list <- keep(fonts, is_bare_list) 105 | 106 | meta <- flatten(lapply(meta, flatten)) 107 | coll <- flatten(coll) 108 | list <- flatten(list) 109 | 110 | if (!all(vapply_lgl(list, inherits, "font"))) { 111 | stop("Lists can contain only `font` objects", call. = FALSE) 112 | } 113 | 114 | fonts <- compact(c(meta, coll, file, list)) 115 | names(fonts) <- vapply_chr(fonts, `[[`, "fullname") 116 | fonts 117 | } 118 | 119 | # R Utils ------------------------------------------------------------ 120 | 121 | `%||%` <- function(x, y) { 122 | if (is.null(x)) y else x 123 | } 124 | 125 | str_standardise <- function(s, sep = "-") { 126 | gsub(" ", sep, tolower(s)) 127 | } 128 | 129 | str_prettify <- function(str) { 130 | if (is.null(str)) return(NULL) 131 | vapply_chr(str, function(s) { 132 | s <- strsplit(s, "-|_| ")[[1]] 133 | paste0(toupper(substring(s, 1, 1)), substring(s, 2), collapse=" ") 134 | }) 135 | } 136 | 137 | str_trim_ext <- function(path) { 138 | sub("\\..+$", "", path) 139 | } 140 | 141 | gather_tree <- function(x, depth) { 142 | if (is.character(depth)) { 143 | depth <- as.list(depth) 144 | } else if (is.numeric(depth)) { 145 | depth <- rep(list(NULL), depth) 146 | } else { 147 | stop("`depth` should be character or numeric", call. = FALSE) 148 | } 149 | 150 | if (length(depth) > 1) { 151 | x <- gather_tree_recurse(x, depth) 152 | } 153 | bind_rows(x, .id = depth[[1]]) 154 | } 155 | 156 | gather_tree_recurse <- function(x, depth) { 157 | if (length(depth) > 1) { 158 | lapply(x, gather_tree_recurse, depth = depth[-1]) 159 | } else { 160 | bind_rows(x, .id = depth[[1]]) 161 | } 162 | } 163 | 164 | at_bottom <- function(.x, .f, ...) { 165 | if (is.list(.x)) { 166 | lapply(.x, at_bottom, .f, ...) 167 | } else { 168 | .f(.x, ...) 169 | } 170 | } 171 | 172 | spread_attributes <- function(x, id) { 173 | stopifnot(is.atomic(x)) 174 | 175 | attrs <- attributes(unclass(x)) 176 | stopifnot(all(vapply_int(attrs, length) == length(x))) 177 | 178 | attrs <- as.data.frame(attrs, stringsAsFactors = FALSE) 179 | df <- cbind(unclass(x), attrs, stringsAsFactors = FALSE) 180 | names(df)[[1]] <- id 181 | 182 | df 183 | } 184 | 185 | set_names <- function(x, nm = x) { 186 | stats::setNames(x, nm) 187 | } 188 | 189 | # Simple reimplementations to avoid dplyr dependency ----------------- 190 | 191 | bind_rows <- function(x, .id = NULL) { 192 | df <- do.call("rbind", unname(x)) 193 | 194 | if (!is.null(.id)) { 195 | lengths <- vapply(x, nrow, numeric(1)) 196 | id <- rep(names(x), lengths) 197 | df <- cbind(id, df, stringsAsFactors = FALSE) 198 | names(df)[[1]] <- .id 199 | } 200 | 201 | df 202 | } 203 | 204 | filter <- function(df, ...) { 205 | fs <- list(...) 206 | stopifnot(all(vapply(fs, inherits, logical(1), "formula"))) 207 | fs <- lapply(fs, `[[`, 2) 208 | 209 | bind_call <- function(lhs, rhs, fun = "&") { 210 | call(fun, lhs, rhs) 211 | } 212 | pattern <- Reduce(bind_call, fs[-1], fs[[1]]) 213 | args <- list(df, pattern, substitute(), drop = FALSE) 214 | 215 | # Assumes all formula envs are identical 216 | env <- as.environment(df) 217 | parent.env(env) <- environment(..1) 218 | do.call("[", args, envir = env) 219 | } 220 | 221 | filter_first <- function(df, ...) { 222 | filtered <- filter(df, ...) 223 | 224 | if (nrow(filtered) > 1) { 225 | filtered[1, , drop = FALSE] 226 | } else { 227 | filtered 228 | } 229 | } 230 | 231 | vapply_ <- function(.x, .f, .mold, ...) { 232 | out <- vapply(.x, .f, .mold, ..., USE.NAMES = FALSE) 233 | stats::setNames(out, names(.x)) 234 | } 235 | vapply_chr <- function(.x, .f, ...) { 236 | vapply_(.x, .f, character(1), ...) 237 | } 238 | vapply_lgl <- function(.x, .f, ...) { 239 | vapply_(.x, .f, logical(1), ...) 240 | } 241 | vapply_int <- function(.x, .f, ...) { 242 | vapply_(.x, .f, integer(1), ...) 243 | } 244 | lapply_if <- function(.x, .p, .f, ...) { 245 | matches <- vapply_lgl(.x, .p) 246 | .x[matches] <- lapply(.x[matches], .f, ...) 247 | .x 248 | } 249 | compact <- function(x) { 250 | Filter(length, x) 251 | } 252 | flatten <- function(.x) { 253 | unlist(.x, FALSE, FALSE) 254 | } 255 | keep <- function(.x, .p, ...) { 256 | .x[vapply_lgl(.x, .p, ...)] 257 | } 258 | is_bare_list <- function(.x) { 259 | is.list(.x) && !is.object(.x) 260 | } 261 | 262 | 263 | # R 3.2.0 compat 264 | dir.exists <- function(paths) { 265 | if (utils::packageVersion("base") >= "3.2.0") { 266 | (baseenv()$dir.exists)(paths) 267 | } else { 268 | vapply_lgl(paths, dir_exists) 269 | } 270 | } 271 | 272 | dir_exists <- function(path) { 273 | !identical(path, "") && file.exists(paste0(path, .Platform$file.sep)) 274 | } 275 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # fontquiver 3 | 4 | fontquiver installs a set of fonts with permissive licences. It is 5 | useful for packages that needs controlled versions of fonts. 6 | 7 | 8 | ## Installation 9 | 10 | Get the development version from github with: 11 | 12 | ```{r} 13 | # install.packages("devtools") 14 | devtools::install_github("lionel-/fontquiver") 15 | ``` 16 | 17 | 18 | ## Usage 19 | 20 | ### Fonts installed in R packages 21 | 22 | fontquiver is an interface to fonts installed as R packages. It 23 | provides convenient and structured access, for instance, to the 24 | Bitstream Vera font family installed with the 25 | [fontBitstreamVera](https://cran.r-project.org/package=fontBitstreamVera) 26 | package, or the Liberation family that comes with 27 | [fontLiberation](https://cran.r-project.org/package=fontLiberation). 28 | The fonts too heavy to be distributed on CRAN can be accessed by 29 | fontquiver through Github-only packages such as 30 | [fontDejaVu](https://github.com/lionel-/fontDejaVu). Each package 31 | bundles a set of fonts (or `fontset` as they are called in fontquiver) 32 | which typically includes bold and italic faces for sans and serif 33 | fonts, but may also include more exotic variations (condensed, ultra 34 | light, etc). Call `fontset_list()` to check which fontsets are 35 | currently installed on your computer. 36 | 37 | Fonts installed in the R library can be useful for a variety of 38 | purposes. They can be used in web applications with the 39 | `htmlFontDependency()` tool. They are also helpful to create 40 | reproducible outputs. An example of this is the `vdiffr` package which 41 | relies on fontquiver to create SVGs that are reproducible across 42 | platforms. Without fontquiver fonts, the SVGs generated by svglite 43 | would have slight differences depending on the versions of the system 44 | fonts used to compute text metrics. 45 | 46 | 47 | ### Categories of fonts 48 | 49 | The standard categories of fonts in R are the `sans`, `serif`, and 50 | `mono` families and the `plain`, `italic`, `bold`, and `bolditalic` 51 | faces. However, font nomenclatures are extremely rich and go well 52 | beyond those 12 categories. For example the DéjàVu set contains a font 53 | whose variant and style are `Serif Condensed` and `Extra Light`. For 54 | this reason, fontquiver uses the categories provided by the font util 55 | `fc-scan` from 56 | [Fontconfig](https://www.freedesktop.org/wiki/Software/fontconfig/). 57 | The terms "variants" and "styles" refer to those categories while 58 | "families" and "faces" refer to R's categories. 59 | 60 | To check which variants and styles are available for a given fontset: 61 | 62 | ```{r} 63 | fontset_variants("DejaVu") 64 | fontset_styles("Bitstream Vera", variant = "Serif") 65 | ``` 66 | 67 | 68 | ### Font getters 69 | 70 | fontquiver provides several getters to access font objects. They all 71 | take a fontset name as argument. They may also take `variant`/`style` 72 | or `family`/`face` arguments. 73 | 74 | `font()` takes a fontest, a variant and a style, and returns an atomic 75 | font object. Those objects contain fields such as `ttf`, `fullname`, 76 | or `version`: 77 | 78 | ```{r} 79 | font("Bitstream Vera", "Sans", "Roman") 80 | font("Bitstream Vera", "Serif", "Bold")$ttf 81 | ``` 82 | 83 | The other getters return collections of fonts. `font_variants()` 84 | returns a tree of lists with the outer list containing all variants of 85 | a fontset and the inner lists containing all styles for a given 86 | variant. Similarly, `font_families()` returns a tree of fonts 87 | structured according to families and faces: 88 | 89 | ```{r} 90 | font_variants("Liberation") 91 | font_families("Liberation") 92 | ``` 93 | 94 | If you need a specific variant or family, `font styles()` and 95 | `font_faces()` return a list of fonts: 96 | 97 | ```{r} 98 | font_styles("DejaVu", "Sans Condensed") 99 | font_faces("DejaVu", "Mono") 100 | ``` 101 | 102 | 103 | ## Applications 104 | 105 | ### Web dependency on an installed font 106 | 107 | The `htmlFontDependency()` tool takes any font object or collection of 108 | font objects. It copies the relevant fonts in `woff` format to a 109 | temporary directory and creates a CSS linking to those fonts. 110 | 111 | ```{r} 112 | # install.packages("htmltools") 113 | 114 | # Create font dependency 115 | liberation <- font_families("Liberation") 116 | mono <- font_styles("DejaVu", "Sans Mono") 117 | html_dep <- htmlFontDependency(liberation, mono) 118 | 119 | span_mono <- htmltools::tags$span( 120 | style = "font-family:'Deja Vu Sans Mono'; font-style:italic;", 121 | "Text rendered with monospace italic font" 122 | ) 123 | span_bold <- htmltools::tags$span( 124 | style = "font-family:'Bitstream Vera Sans'; font-weight:700;", 125 | "Text rendered with sans bold font" 126 | ) 127 | 128 | # Add font dependency to an HTML object and print 129 | text <- htmltools::div(span_mono, span_bold, html_dep) 130 | htmltools::html_print(text) 131 | ``` 132 | 133 | 134 | ### User fonts in svglite 135 | 136 | You can supply fontquiver fonts to `svglite`: 137 | 138 | ```{r} 139 | svglite::stringSVG(user_fonts = font_families("Liberation"), { 140 | plot(1:10) 141 | }) 142 | ``` 143 | 144 | See the fonts vignette in the svglite package for more about this. 145 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Test environments 2 | * local OS X install, R 3.3.2 and R 3.1.3 3 | * ubuntu 12.04 (on travis-ci), R 3.3.2 4 | * win-builder (devel and release) 5 | 6 | ## R CMD check results 7 | 8 | 0 errors | 0 warnings | 0 note 9 | 10 | ## Reverse dependencies 11 | 12 | Checked svglite and vdiffr. 13 | 14 | This release is meant to fix a dependency issue with ggstance on oldrel R. 15 | 16 | --- 17 | -------------------------------------------------------------------------------- /fontquiver.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /inst/fonts/symbola-VERSION: -------------------------------------------------------------------------------- 1 | 9.00 2 | -------------------------------------------------------------------------------- /inst/fonts/symbola-fonts/Symbola.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lionel-/fontquiver/fcb3d601b4759afe7b46455622eca40ab1350013/inst/fonts/symbola-fonts/Symbola.ttf -------------------------------------------------------------------------------- /inst/fonts/symbola-fonts/Symbola.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lionel-/fontquiver/fcb3d601b4759afe7b46455622eca40ab1350013/inst/fonts/symbola-fonts/Symbola.woff -------------------------------------------------------------------------------- /man/font_families.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/font-getters.R 3 | \name{font_families} 4 | \alias{font_faces} 5 | \alias{font_families} 6 | \title{Font families and faces} 7 | \usage{ 8 | font_families(fontset) 9 | 10 | font_faces(fontset, family = c("sans", "serif", "mono", "symbol")) 11 | } 12 | \arguments{ 13 | \item{fontset}{A string giving the name of a set of fonts 14 | (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 15 | \code{\link{fontset_list}()} to obtain the list of fontsets 16 | registered in your session.} 17 | 18 | \item{family}{One of \code{"sans"}, \code{"serif"}, \code{"mono"} 19 | or \code{"symbol"}.} 20 | } 21 | \description{ 22 | Returns families or faces as font files for a given font set. The 23 | files are organised by R nomenclature of families (\code{"sans"}, 24 | \code{"serif"}, \code{"mono"}, and \code{"symbol"}) and faces 25 | (\code{"plain"}, \code{"italic"}, \code{"bold"}, and 26 | \code{"bolditalic"}). When a font does not have a combination, 27 | \code{NA} is reported. 28 | } 29 | \details{ 30 | Note that the fonts returned by \code{font_faces()} and 31 | \code{\link{font_families}()} are constrained by R's nomenclature 32 | of fonts and are thus a subset of those returned by 33 | \code{\link{font_variants}()} and \code{\link{font_styles}()}. 34 | } 35 | \examples{ 36 | font_families("Bitstream Vera")$mono$bold 37 | font_faces("Bitstream Vera", "mono") 38 | } 39 | \seealso{ 40 | \code{\link{font_variants}()}, \code{\link{fonts}()} 41 | } 42 | 43 | -------------------------------------------------------------------------------- /man/font_variants.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/font-getters.R 3 | \name{font_variants} 4 | \alias{font_styles} 5 | \alias{font_variants} 6 | \title{Font variants} 7 | \usage{ 8 | font_variants(fontset) 9 | 10 | font_styles(fontset, variant) 11 | } 12 | \arguments{ 13 | \item{fontset}{A string giving the name of a set of fonts 14 | (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 15 | \code{\link{fontset_list}()} to obtain the list of fontsets 16 | registered in your session.} 17 | 18 | \item{variant}{Font variant, as per Fontconfig's nomenclature. Use 19 | \code{\link{fontset_variants}()} to find out which variants are 20 | available for a fontset.} 21 | } 22 | \description{ 23 | \code{font_variants()} returns a tree of fonts organised as per 24 | fontconfig's nomenclature. The first level contains variants of a 25 | font and the second level contains font styles. 26 | } 27 | \details{ 28 | See also \code{\link{font_families}()} and \code{\link{font_faces}()} 29 | for similar collections organised according to R nomenclature of 30 | fonts. Note that variants and styles are a super set of R families 31 | and faces and may contain more fonts. 32 | } 33 | \examples{ 34 | font_variants("Bitstream Vera") 35 | font_variants("Bitstream Vera")$Sans$Oblique 36 | font_styles("Bitstream Vera", "Sans") 37 | } 38 | \seealso{ 39 | \code{\link{font_families}()}, \code{\link{fonts}()} 40 | } 41 | 42 | -------------------------------------------------------------------------------- /man/fonts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/font-getters.R 3 | \name{fonts} 4 | \alias{font} 5 | \alias{font_symbol} 6 | \alias{fonts} 7 | \title{Get elements of a fontset} 8 | \usage{ 9 | fonts(fontset) 10 | 11 | font(fontset, variant, style) 12 | 13 | font_symbol(fontset = "Symbola") 14 | } 15 | \arguments{ 16 | \item{fontset}{A string giving the name of a set of fonts 17 | (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 18 | \code{\link{fontset_list}()} to obtain the list of fontsets 19 | registered in your session.} 20 | 21 | \item{variant}{Font variant, as per Fontconfig's nomenclature. Use 22 | \code{\link{fontset_variants}()} to find out which variants are 23 | available for a fontset.} 24 | 25 | \item{style}{Font style, as per Fontconfig's nomenclature. Use 26 | \code{\link{fontset_styles}()} to find out which variants are 27 | available for a fontset.} 28 | } 29 | \description{ 30 | \code{fonts()} returns the list of all \code{font} objects for a 31 | given fontset (a collection of fonts provided by fontquiver, such 32 | as \code{Liberation} or \code{Bitstream Vera}). \code{font()} 33 | returns one specific font. \code{font_symbol()} extracts the font 34 | marked as symbol font, if it exists in the fontset. 35 | } 36 | \examples{ 37 | font("Bitstream Vera", "Sans", "Roman") 38 | 39 | f <- fonts("Liberation") 40 | str(f, 1) 41 | 42 | font_symbol("Symbola") 43 | } 44 | 45 | -------------------------------------------------------------------------------- /man/fontset_info.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fontset.R 3 | \name{fontset_info} 4 | \alias{fontset_info} 5 | \title{Fontset metadata} 6 | \usage{ 7 | fontset_info(fontset) 8 | } 9 | \arguments{ 10 | \item{fontset}{A string giving the name of a set of fonts 11 | (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 12 | \code{\link{fontset_list}()} to obtain the list of fontsets 13 | registered in your session.} 14 | } 15 | \description{ 16 | This returns a data frame containing metadata about fonts. The 17 | columns "variant" and "style" correspond to the properties of the 18 | font as reported by fontconfig. The columns "family", "italic" and 19 | "bold" provide information in terms of R nomenclature of fonts. The 20 | column "base" gives the base filename of the font. See 21 | \code{\link{fontset_list}()} to obtain a list of available 22 | fontsets. 23 | } 24 | \seealso{ 25 | \code{\link{fontset_list}()}, \code{\link{font_families}()}, 26 | \code{\link{font_variants}()} 27 | } 28 | 29 | -------------------------------------------------------------------------------- /man/fontset_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fontset.R 3 | \name{fontset_list} 4 | \alias{fontset_list} 5 | \title{Get list of all registered fonts} 6 | \usage{ 7 | fontset_list() 8 | } 9 | \description{ 10 | Get list of all registered fonts 11 | } 12 | 13 | -------------------------------------------------------------------------------- /man/fontset_register.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fontset.R 3 | \name{fontset_register} 4 | \alias{fontset_register} 5 | \title{Register a font to fontquiver} 6 | \usage{ 7 | fontset_register(fontset, getter, files) 8 | } 9 | \arguments{ 10 | \item{fontset}{Name of the font set.} 11 | 12 | \item{getter}{Constructor of \code{font} objects.} 13 | 14 | \item{files}{Data structure containing font information.} 15 | } 16 | \description{ 17 | Register a font to fontquiver 18 | } 19 | 20 | -------------------------------------------------------------------------------- /man/fontset_variants.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fontset.R 3 | \name{fontset_variants} 4 | \alias{fontset_styles} 5 | \alias{fontset_variants} 6 | \title{Fontset variants and styles} 7 | \usage{ 8 | fontset_variants(fontset) 9 | 10 | fontset_styles(fontset, variant) 11 | } 12 | \arguments{ 13 | \item{fontset}{A string giving the name of a set of fonts 14 | (e.g. \code{"Liberation"} or\code{"Bitstream Vera"}). Use 15 | \code{\link{fontset_list}()} to obtain the list of fontsets 16 | registered in your session.} 17 | 18 | \item{variant}{Font variant, as per Fontconfig's nomenclature. Use 19 | \code{\link{fontset_variants}()} to find out which variants are 20 | available for a fontset.} 21 | } 22 | \description{ 23 | These functions return the variants and the styles available for a 24 | given fontset. 25 | } 26 | \examples{ 27 | fontset_variants("Liberation") 28 | fontset_styles("Bitstream Vera", "Sans Mono") 29 | } 30 | 31 | -------------------------------------------------------------------------------- /man/htmlFontDependency.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/html-dependency.R 3 | \name{htmlFontDependency} 4 | \alias{htmlFontDependency} 5 | \title{Include font as CSS dependency} 6 | \usage{ 7 | htmlFontDependency(...) 8 | } 9 | \arguments{ 10 | \item{...}{Fonts or collections of fonts. See 11 | \code{\link{font_families}()} and \code{\link{font_variants}()} 12 | for creating collections of fonts. You can also supply lists of 13 | individual fonts as returned by \code{\link{fonts}()}.} 14 | } 15 | \description{ 16 | Include font as CSS dependency 17 | } 18 | \examples{ 19 | # Create an htmlDependency object: 20 | dep <- htmlFontDependency(font_families("Bitstream Vera")) 21 | 22 | # Use the fonts in your dependent css or html files. For example: 23 | # body { 24 | # font-family: 'Bitstream Vera Sans Mono', courier; 25 | # } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /man/splice_fonts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{splice_fonts} 4 | \alias{splice_fonts} 5 | \title{Splice fonts and font collections} 6 | \usage{ 7 | splice_fonts(...) 8 | } 9 | \arguments{ 10 | \item{...}{Fonts or collections of fonts. See 11 | \code{\link{font_families}()} and \code{\link{font_variants}()} 12 | for creating collections of fonts. You can also supply lists of 13 | individual fonts as returned by \code{\link{fonts}()}.} 14 | } 15 | \description{ 16 | \code{splice_fonts()} Reduces its arguments to a flat list. It 17 | accepts indinstinctly \code{font} objects, lists of \code{font} 18 | objects (obtained with \code{\link{fonts}()}), or collections of 19 | fonts produced by \code{\link{font_variants}()} or 20 | \code{\link{font_families}()}. Duplicate fonts are removed from the 21 | result. 22 | } 23 | \examples{ 24 | splice_fonts(font("Bitstream Vera", "Sans", "Oblique"), font_faces("Bitstream Vera", "mono")) 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(fontquiver) 3 | 4 | test_check("fontquiver") 5 | -------------------------------------------------------------------------------- /tests/testthat/test-fonts.R: -------------------------------------------------------------------------------- 1 | 2 | context("Fontset Files") 3 | 4 | check_fontset_files <- function(files, font_getter) { 5 | Map(function(styles, variant) { 6 | fonts <- lapply(names(styles), font_getter, variant = variant) 7 | not_found <- fonts == "" 8 | info <- paste(variant, ": ", names(styles)[not_found], collapse = ", ", sep = "") 9 | expect_false(any(not_found), info) 10 | }, files, names(files)) 11 | } 12 | 13 | test_that("Bitstream Vera files are found", { 14 | check_fontset_files(fontset_bitstream_vera_files, fontset_bitstream_vera) 15 | }) 16 | 17 | test_that("DejaVu files are found", { 18 | if (check_font_exists("dejavu", "fontDejaVu")) { 19 | check_fontset_files(fontset_dejavu_files, fontset_dejavu) 20 | } 21 | }) 22 | 23 | test_that("Liberation files are found", { 24 | check_fontset_files(fontset_liberation_files, fontset_liberation) 25 | }) 26 | 27 | test_that("Symbola file is found", { 28 | check_fontset_files(fontset_symbola_files, fontset_symbola) 29 | }) 30 | -------------------------------------------------------------------------------- /tests/testthat/test-html-dependency.R: -------------------------------------------------------------------------------- 1 | 2 | context("htmlDependency") 3 | 4 | test_that("throw when malformed list is supplied", { 5 | fonts <- list(fontset_bitstream_vera(), mtcars) 6 | expect_error(htmlFontDependency(fonts), "can contain only") 7 | }) 8 | 9 | test_that("throw when non-font object is supplied", { 10 | expect_error(htmlFontDependency(mtcars), "Unknown class") 11 | }) 12 | 13 | test_that("font collections are spliced", { 14 | variants <- font_variants("Bitstream Vera") 15 | families <- font_families("Bitstream Vera") 16 | styles <- font_styles("Bitstream Vera", "Sans Mono") 17 | faces <- font_faces("Bitstream Vera", "mono") 18 | 19 | expect_length(splice_fonts(variants), 10) 20 | expect_length(splice_fonts(families), 10) 21 | expect_length(splice_fonts(styles), 4) 22 | expect_length(splice_fonts(faces), 4) 23 | expect_length(splice_fonts(variants, families, styles, faces), 28) 24 | }) 25 | --------------------------------------------------------------------------------