wilkelab / ggtext

Improved text rendering support for ggplot2
https://wilkelab.org/ggtext/
GNU General Public License v2.0
650 stars 37 forks source link

MD bold face don't work and `face = "bold"` renders without kerning adjustment in R 4.2.0 RC #81

Closed netique closed 2 years ago

netique commented 2 years ago

Hi,

R 4.2.0 is gonna be out in just a few days. I have the up-to-date RC build installed and I have spotted ggtext fails to render text that rendered just fine under R 4.1.3. Most notably, MD markup is not working anymore (tested with ** **).

When I try to specify face via the face argument in element_textbox or element_markdown, the resulting text is bold, but the kerning is messed up to the point where whitespaces seem to be removed.

I tried to build ggtext and gridtext both from source, but there is no difference to macOS binaries from CRAN that are available for RC versions.

Plain text works fine:

library(ggplot2)
library(ggtext)

ggplot() +
  labs(title = "Fuel economy vs. **engine displacement**") +
  theme(
    plot.title.position = "plot",
    plot.title = element_textbox(size = 20)
  )

Bold is not possible or renders with erroneous kerning:


ggplot() +
  labs(title = "Fuel economy vs. engine displacement") +
  theme(
    plot.title.position = "plot",
    plot.title = element_textbox(size = 20, face = "bold")
  )

Created on 2022-04-20 by the reprex package (v2.0.1)

Session info ``` r sessionInfo() #> R version 4.2.0 RC (2022-04-19 r82217) #> Platform: aarch64-apple-darwin20 (64-bit) #> Running under: macOS Monterey 12.3.1 #> #> Matrix products: default #> BLAS: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRblas.0.dylib #> LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib #> #> locale: #> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 #> #> attached base packages: #> [1] stats graphics grDevices utils datasets methods base #> #> other attached packages: #> [1] ggtext_0.1.1 ggplot2_3.3.5 #> #> loaded via a namespace (and not attached): #> [1] Rcpp_1.0.8.3 pillar_1.7.0 compiler_4.2.0 #> [4] highr_0.9 R.methodsS3_1.8.1 R.utils_2.11.0 #> [7] tools_4.2.0 digest_0.6.29 evaluate_0.15 #> [10] lifecycle_1.0.1 tibble_3.1.6 gtable_0.3.0 #> [13] R.cache_0.15.0 pkgconfig_2.0.3 rlang_1.0.2 #> [16] reprex_2.0.1 DBI_1.1.2 cli_3.2.0 #> [19] rstudioapi_0.13 curl_4.3.2 yaml_2.3.5 #> [22] xfun_0.30 fastmap_1.1.0 httr_1.4.2 #> [25] xml2_1.3.3 dplyr_1.0.8 withr_2.5.0 #> [28] styler_1.7.0 stringr_1.4.0 knitr_1.38 #> [31] generics_0.1.2 fs_1.5.2 vctrs_0.4.1 #> [34] gridtext_0.1.4.9000 tidyselect_1.1.2 grid_4.2.0 #> [37] glue_1.6.2 R6_2.5.1 fansi_1.0.3 #> [40] rmarkdown_2.13 purrr_0.3.4 magrittr_2.0.3 #> [43] scales_1.2.0 ellipsis_0.3.2 htmltools_0.5.2 #> [46] assertthat_0.2.1 mime_0.12 colorspace_2.0-3 #> [49] utf8_1.2.2 stringi_1.7.6 munsell_0.5.0 #> [52] markdown_1.1 crayon_1.5.1 R.oo_1.24.0 ```
netique commented 2 years ago

Note there is no issue with

grid.newpage()
grid.text("Fuel economy vs. engine displacement", x=.5, y=.5,
          gp=gpar(fontsize=20, fontface= "bold"))

Interestingly, I found those errors when browsing plots in RStudio:

Error in bl_calc_layout(vbox_outer, width_pt) : 
  external pointer is not valid
Graphics error: Plot rendering error
clauswilke commented 2 years ago

Thanks for pointing this out. Unfortunately I don't have the capacity right now to look into this in detail. If somebody is willing to dig, I could provide pointers to where to look.

A couple of questions/thoughts:

  1. What OS are you using? It'd be important to figure out whether this is specific to one OS or a general problem with R 4.2.

  2. If kerning is messed up, this most likely means font metrics are being retrieved incorrectly. This might be a relatively easy fix. In fact, maybe it's only the size of a space that is calculated incorrectly? It looks to me like kerning within words is fine.

netique commented 2 years ago

Sure! Maybe it's macOS related only (full Session Info under the reprex + I've just tested _x8664 R and the issue is the same). If anybody could test it on Windows, that would be great.

Meanwhile, I tested Quartz and AGG devices with no success. Nor R 4.2.0 "vanilla" console works as it previously has.

Unfortunately, I am fairly new to C++... I skimmed src in gridtext, but nothing catched my eye. If @clauswilke you could point me to any "suspicious" locations, maybe I'll try some trial-and-error like attempts.

clauswilke commented 2 years ago

I would expect the problem to be located here: https://github.com/wilkelab/gridtext/blob/8c8fb73128f17d9f135fe20f985757312418c49a/R/text-details.R#L56-L64

This is pure R code, so should be easy to debug. The question is whether this code properly returns the width of a space character. If it doesn't then you have located the issue. One solution then could be to look up the width of a string containing a space (e.g., "w w") and subtract the width of the same string without space ("ww").

We should probably move this over to gridtext though, as that's the package that does the heavy lifting: https://github.com/wilkelab/gridtext/

clauswilke commented 2 years ago

The other problem could be that some assumptions of the font caching mechanism aren't valid anymore. In that case, the fix would be to just turn off font caching. It would make things slower but more reliable, so that might be the right thing to do anyways. A quick way to turn off font caching is to change this line to if (TRUE){...: https://github.com/wilkelab/gridtext/blob/8c8fb73128f17d9f135fe20f985757312418c49a/R/text-details.R#L45

netique commented 2 years ago

Ok, many thanks! For now, circumventing the cache did not help.

clauswilke commented 2 years ago

Yeah, my first guess would not have been the cache but rather the width of a grob containing only a space (i.e., the first issue I pointed out).

Closing this in favor of: https://github.com/wilkelab/gridtext/issues/24