rstudio / thematic

Theme ggplot2, lattice, and base graphics based on a few simple settings.
https://rstudio.github.io/thematic/
Other
244 stars 10 forks source link

issues with ragg/systemfonts #107

Closed kbzsl closed 3 years ago

kbzsl commented 3 years ago

I was trying to define custom fonts with bslib + thematic. It looks that the thematic is not working with ragg/systemfonts when knitting the html document (on a windows machine). I am receiving the following warnings, even though the knitr::opts_chunk$set(dev = "ragg_png") was set

## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family 'Cambria' not found, will use 'sans'
## instead

The pixel peeping (extracting the plot from the html documents) suggests also that not the ragg graphic device was used when knitting this html document. On the other hand, when removing the thematic definition (thematic::thematic_rmd(font = "auto")), the document was knitted correctly.

Rmd file:


---
title: "custom font test"
subtitle: "rmarkdown html_document, bslib"
output: 
  html_document:
    theme:
      version: 4
      base_font: "Cambria"
      code_font: "Consolas"
---

```{r setup, message=FALSE}
thematic::thematic_rmd(font = "auto")

knitr::opts_chunk$set(dev = "ragg_png")
knitr::opts_chunk$set(echo = TRUE)
knitr::opts_chunk$set(fig.width = 5, fig.height = 2, dpi = 150)
options(width = 120)

library(tidyverse)
library(systemfonts)
library(ragg)
```

Let's check the fonts using the [systemfonts](https://cran.r-project.org/web/packages/systemfonts/index.html) package. You can guess easily that this was knit on a windows machine.

```{r fonts}
system_fonts() %>%
  filter(str_detect(name, "Cambria"))

system_fonts() %>%
  filter(str_detect(name, "Consolas"))
```

And create some demo plots using these fonts.

```{r}
p <- mtcars %>%
  ggplot(aes(mpg, hp)) +
  geom_point(color = "#0082F0", size = 4, alpha = 0.3) +
  ggtitle(paste("FONT TEST:", "the default font"),
          subtitle = "9876543210123456789") +
  theme_classic()

print(p)
```

```{r}
p <- mtcars %>%
  ggplot(aes(mpg, hp)) +
  geom_point(color = "#0082F0", size = 4, alpha = 0.3) +
  ggtitle(paste("FONT TEST:", "Cambria"),
          subtitle = "9876543210123456789") +
  theme_classic(base_family = "Cambria")

print(p)
```

```{r}
p <- mtcars %>%
  ggplot(aes(mpg, hp)) +
  geom_point(color = "#0082F0", size = 4, alpha = 0.3) +
  ggtitle(paste("FONT TEST:", "Consolas"),
          subtitle = "9876543210123456789") +
  theme_classic(base_family = "Consolas")

print(p)
```

Session Info


- Session info -----------------------------------------------------------------------------
 setting  value                       
 version  R version 4.1.0 (2021-05-18)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RStudio                     
 language (EN)                        
 collate  English_United States.1252  
 ctype    English_United States.1252  
 tz       Europe/Prague               
 date     2021-07-15                  

- Packages ---------------------------------------------------------------------------------
 package     * version date       lib source        
 cachem        1.0.5   2021-05-15 [2] CRAN (R 4.1.0)
 callr         3.7.0   2021-04-20 [2] CRAN (R 4.1.0)
 cli           3.0.0   2021-06-30 [2] CRAN (R 4.1.0)
 crayon        1.4.1   2021-02-08 [2] CRAN (R 4.1.0)
 desc          1.3.0   2021-03-05 [2] CRAN (R 4.1.0)
 devtools      2.4.2   2021-06-07 [2] CRAN (R 4.1.0)
 digest        0.6.27  2020-10-24 [2] CRAN (R 4.1.0)
 ellipsis      0.3.2   2021-04-29 [2] CRAN (R 4.1.0)
 evaluate      0.14    2019-05-28 [2] CRAN (R 4.1.0)
 fastmap       1.1.0   2021-01-25 [2] CRAN (R 4.1.0)
 fs            1.5.0   2020-07-31 [2] CRAN (R 4.1.0)
 glue          1.4.2   2020-08-27 [2] CRAN (R 4.1.0)
 htmltools     0.5.1.1 2021-01-22 [2] CRAN (R 4.1.0)
 knitr         1.33    2021-04-24 [2] CRAN (R 4.1.0)
 lifecycle     1.0.0   2021-02-15 [2] CRAN (R 4.1.0)
 magrittr      2.0.1   2020-11-17 [2] CRAN (R 4.1.0)
 memoise       2.0.0   2021-01-26 [2] CRAN (R 4.1.0)
 pkgbuild      1.2.0   2020-12-15 [2] CRAN (R 4.1.0)
 pkgload       1.2.1   2021-04-06 [2] CRAN (R 4.1.0)
 prettyunits   1.1.1   2020-01-24 [2] CRAN (R 4.1.0)
 processx      3.5.2   2021-04-30 [2] CRAN (R 4.1.0)
 ps            1.6.0   2021-02-28 [2] CRAN (R 4.1.0)
 purrr         0.3.4   2020-04-17 [2] CRAN (R 4.1.0)
 R6            2.5.0   2020-10-28 [2] CRAN (R 4.1.0)
 remotes       2.4.0   2021-06-02 [2] CRAN (R 4.1.0)
 rlang         0.4.11  2021-04-30 [2] CRAN (R 4.1.0)
 rmarkdown     2.9     2021-06-15 [2] CRAN (R 4.1.0)
 rprojroot     2.0.2   2020-11-15 [2] CRAN (R 4.1.0)
 rstudioapi    0.13    2020-11-12 [2] CRAN (R 4.1.0)
 sessioninfo   1.1.1   2018-11-05 [2] CRAN (R 4.1.0)
 testthat      3.0.4   2021-07-01 [2] CRAN (R 4.1.0)
 thematic    * 0.1.2.1 2021-06-09 [1] CRAN (R 4.1.0)
 usethis       2.0.1   2021-02-10 [2] CRAN (R 4.1.0)
 withr         2.4.2   2021-04-18 [2] CRAN (R 4.1.0)
 xfun          0.24    2021-06-15 [2] CRAN (R 4.1.0)
 yaml          2.2.1   2020-02-01 [2] CRAN (R 4.1.0)
cpsievert commented 3 years ago

Cambria isn't a Google Font, so thematic doesn't know how to automatically install/register it https://rstudio.github.io/thematic/articles/fonts.html#google-fonts

Instead, you'll have to provide the font files directly to either sysfonts::font_add() or systemfonts::register_font() https://rstudio.github.io/thematic/articles/fonts.html#other-fonts

kbzsl commented 3 years ago

Hi @cpsievert,

The recommended is not working, because family name already exists (according to the systemfonts):


library(tidyverse)
library(systemfonts)

system_fonts() %>%
  filter(str_detect(name, "Consolas"))
#> # A tibble: 4 x 9
#>   path             index name       family style   weight width italic monospace
#>                                    
#> 1 "C:\\WINDOWS\\F~     0 Consolas   Conso~ Regular normal norm~ FALSE  TRUE     
#> 2 "C:\\WINDOWS\\F~     0 Consolas-~ Conso~ Bold    bold   norm~ FALSE  TRUE     
#> 3 "C:\\WINDOWS\\F~     0 Consolas-~ Conso~ Bold I~ bold   norm~ TRUE   TRUE     
#> 4 "C:\\WINDOWS\\F~     0 Consolas-~ Conso~ Italic  normal norm~ TRUE   TRUE

register_font(name = "Consolas",
              "C:\\WINDOWS\\Fonts\\consola.ttf")
#> Error: A system font with that family name already exists

On the other hand, (as I wrote) when I keep the blisbdefinition in the YAMLheader, and I remove just the one line of the thematic, this Rmd is knitted perfectly to the html. What is the reason why this code is working with the bslib, but not working when the thematicis added?

Thank you.

cpsievert commented 3 years ago

The warning is about Cambria, not Consolas (that font appears to be already installed and registered with R on your system).

What is the reason why this code is working with the bslib , but not working when the thematic is added?

HTML/CSS (i.e., bslib) fonts are rendered by the web browser, not the R graphics device.

kbzsl commented 3 years ago

Hi @cpsievert,

Sorry, you are right. I way trying many different fonts (installed by default on windows), and regardless the font the result was the same. The systemfonts recognize, Cambria, too.


library(tidyverse)
library(systemfonts)

system_fonts() %>%
  filter(str_detect(name, "Cambria"))
#> # A tibble: 5 x 9
#>   path            index name       family   style  weight width italic monospace
#>                                    
#> 1 "C:\\WINDOWS\\~     0 Cambria    Cambria  Regul~ normal norm~ FALSE  FALSE    
#> 2 "C:\\WINDOWS\\~     1 CambriaMa~ Cambria~ Regul~ normal norm~ FALSE  FALSE    
#> 3 "C:\\WINDOWS\\~     0 Cambria-B~ Cambria  Bold   bold   norm~ FALSE  FALSE    
#> 4 "C:\\WINDOWS\\~     0 Cambria-B~ Cambria  Bold ~ bold   norm~ TRUE   FALSE    
#> 5 "C:\\WINDOWS\\~     0 Cambria-I~ Cambria  Italic normal norm~ TRUE   FALSE

register_font(name = "Cambria",
              "C:\\WINDOWS\\Fonts\\cambria.ttc")
#> Error: A system font with that family name already exists

Sorry for my wording, I was referring to the plots. It’s a bit strange when having only the bslib definition the plots are rendered correctly (ragg_png), but when the thematic definition is added the plots are not rendered anymore correctly (nor Cambria, nor Consolas...).

Thank you.

cpsievert commented 3 years ago

when the thematic definition is added the plots are not rendered anymore correctly

Have you tried using these fonts without thematic? If neither of these examples work, the problem resides in ragg/showtext, not thematic.

library(ragg)
agg_png("ragg.png")
plot(1, family = "Cambria")
dev.off()
file.show("ragg.png")
library(showtext)
png("showtext.png")
showtext_begin()
plot(1, family = "Cambria")
dev.off()
file.show("showtext.png")
kbzsl commented 3 years ago

Hi @cpsievert,

Yes, as I wrote, when I comment out the single line containing thematic definition, the Rmd file is rendered correctly, both the text body (which is rendered in fact by the browser) and all the plots are containing the expected fonts. Is it possible to share the rendered htmls?

Running the code snippets that you provided, the showtext version is generating a lot of warning for the font (sans is used instead). The ragg version is running without any error, but is not rendered correctly (axis text is missing).

Thank you.

kbzsl commented 3 years ago

Hi @cpsievert

I am trying to rephrase my issue and add extra sreenshots to explain my findings/concerns. It might happen that I misunderstood something in the documentation or other materials, but still I cannot find an explanation, nor solution.

This time, I am using the Lucida fonts, which is an easily distinguishable font family (and which is installed by default on most of window machines).

There are two Rmd files, the only difference is that the thematic::thematic_rmd() line is commented out in the version without thematic.

The first version (_custom_font_test_withbslib.Rmd) includes only bslibdefinitions. The rendered results are ok: the fonts in the text and code parts are ok (this part is rendered by the browser); and all the plots (the title and subtitle part) are rendered using the right fonts. custom_font_test_with_bslib_1 custom_font_test_with_bslib_2 custom_font_test_with_bslib_3

After adding the thematicdefinition (_custom_font_test_with_bslibthematic.Rmd) I run into problems. I expected that the thematic will propagate the font settings (base_font: "Lucida Handwriting") in case of the first plot, where the font family is not explicitly set - but this not happened. The next two plots, where the font families were explicitly set, are not rendered correctly and there are font not found warnings: _Warning in grid.Call(CstringMetric, as.graphicsAnnot(x$label)): font family - but this was working fine previously, and now the fonts which are know to the systemfontsare not "recognized" anymore. For this reason I am notifying: @thomasp85

custom_font_test_with_bslib_thematic_1 custom_font_test_with_bslib_thematic_2 custom_font_test_with_bslib_thematic_3

Thank you.

custom_font_test_with_bslib.Rmd


---
title: "custom font test using local fonts"
subtitle: "with bslib"
output: 
  html_document:
    theme:
      version: 4
      base_font: "Lucida Handwriting"
      code_font: "Lucida Console"
---

```{r setup, message=FALSE}
# thematic::thematic_rmd()

knitr::opts_chunk$set(dev = "ragg_png",
                      fig.width = 5, fig.height = 1, dpi = 300)

library(tidyverse)
library(systemfonts)
library(ragg)

font_test <- function(font_family = NULL){
  ggplot(NULL) +
  ggtitle("The quick brown fox jumps over the lazy dog",
          subtitle = "01234567890987654321012345678909876543210") +
  theme_classic(base_family = font_family)
}
```

ggplot rendered using the **default** font 

```{r}
font_test()
```

ggplot rendered using the **Lucida Handwriting** font 

```{r}
system_fonts() |> 
  filter(str_detect(family, "Lucida Handwriting")) |> 
  glimpse()

font_test("Lucida Handwriting")
```

ggplot rendered using the **Lucida Console** font 

```{r}
system_fonts() |> 
  filter(str_detect(family, "Lucida Console")) |> 
  glimpse()

font_test("Lucida Console")
```

custom_font_test_with_bslib_thematic.Rmd


---
title: "custom font test using local fonts"
subtitle: "with bslib and thematic"
output: 
  html_document:
    theme:
      version: 4
      base_font: "Lucida Handwriting"
      code_font: "Lucida Console"
---

```{r setup, message=FALSE}
thematic::thematic_rmd()

knitr::opts_chunk$set(dev = "ragg_png",
                      fig.width = 5, fig.height = 1, dpi = 300)

library(tidyverse)
library(systemfonts)
library(ragg)

font_test <- function(font_family = NULL){
  ggplot(NULL) +
  ggtitle("The quick brown fox jumps over the lazy dog",
          subtitle = "01234567890987654321012345678909876543210") +
  theme_classic(base_family = font_family)
}
```

ggplot rendered using the **default** font 

```{r}
font_test()
```

ggplot rendered using the **Lucida Handwriting** font 

```{r}
system_fonts() |> 
  filter(str_detect(family, "Lucida Handwriting")) |> 
  glimpse()

font_test("Lucida Handwriting")
```

ggplot rendered using the **Lucida Console** font 

```{r}
system_fonts() |> 
  filter(str_detect(family, "Lucida Console")) |> 
  glimpse()

font_test("Lucida Console")
```