From 7a4e63d90de8fb8237b013baa066909f5e755265 Mon Sep 17 00:00:00 2001 From: Trevor L Davis Date: Tue, 23 Apr 2024 11:26:08 -0700 Subject: [PATCH] feat: 'clippingPathGrob()' and 'alphaMaskGrob()' improvements * `clippingPathGrob()` can now more efficiently compute a `rasterGrob()` approximation via `ragg::agg_capture()` and for `png_device` functions that support the clipping path feature such as`png(type = "cairo")`(#74). * `alphaMaskGrob()` can now more efficiently compute a `rasterGrob()` approximation for `png_device` functions that support the alpha mask feature such as`png(type = "cairo")`(#75). * `alphaMaskGrob()` and `clippingPathGrob()` now switch back to the previously open graphics device if they open and close any new graphics devices. closes #74, closes #75 --- DESCRIPTION | 2 +- NAMESPACE | 1 + NEWS.md | 13 +++ R/alphaMaskGrob.R | 98 ++++++++++++------ R/clippingPathGrob.R | 95 +++++++++++++---- R/gridpattern-package.R | 2 +- R/utils-polygon_df.R | 6 +- R/zzz.R | 2 +- man/clippingPathGrob.Rd | 9 +- man/gridpattern-package.Rd | 2 +- ...nsparent.png => alphaMaskGrob_feature.png} | Bin tests/figs/array/alphaMaskGrob_manual.png | Bin 0 -> 4304 bytes ...phaMaskGrob.png => alphaMaskGrob_ragg.png} | Bin tests/figs/array/clipGrob_cairo.png | Bin 0 -> 17833 bytes tests/figs/array/clipGrob_feature.png | Bin 0 -> 17854 bytes .../{clipGrob.png => clipGrob_manual.png} | Bin tests/figs/array/clipGrob_ragg.png | Bin 0 -> 17473 bytes tests/testthat/test_array.R | 56 ++++++---- 18 files changed, 205 insertions(+), 81 deletions(-) rename tests/figs/array/{alphaMaskGrob_transparent.png => alphaMaskGrob_feature.png} (100%) create mode 100644 tests/figs/array/alphaMaskGrob_manual.png rename tests/figs/array/{alphaMaskGrob.png => alphaMaskGrob_ragg.png} (100%) create mode 100644 tests/figs/array/clipGrob_cairo.png create mode 100644 tests/figs/array/clipGrob_feature.png rename tests/figs/array/{clipGrob.png => clipGrob_manual.png} (100%) create mode 100644 tests/figs/array/clipGrob_ragg.png diff --git a/DESCRIPTION b/DESCRIPTION index e862328..d82dd48 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: gridpattern Type: Package Title: 'grid' Pattern Grobs -Version: 1.2.0-4 +Version: 1.2.0-5 Authors@R: c(person("Mike", "FC", role = "aut", comment = "Code/docs adapted from ggpattern"), person("Trevor L.", "Davis", role=c("aut", "cre"), email="trevor.l.davis@gmail.com", comment = c(ORCID = "0000-0001-6341-4639")), diff --git a/NAMESPACE b/NAMESPACE index 734b99c..ae75e1f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -55,6 +55,7 @@ import(grid) importFrom(glue,glue) importFrom(grDevices,col2rgb) importFrom(grDevices,dev.capabilities) +importFrom(grDevices,dev.capture) importFrom(grDevices,dev.off) importFrom(grDevices,png) importFrom(grDevices,rgb) diff --git a/NEWS.md b/NEWS.md index 672396c..dbaaf2a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,19 @@ New Features * For completeness there is now a `grid.pattern_none()` corresponding to the previously supported "none" pattern which draws nothing. +Bug fixes and minor improvements +-------------------------------- + +* `clippingPathGrob()` can now more efficiently compute a `rasterGrob()` approximation + via `ragg::agg_capture()` and for `png_device` functions that support + the clipping path feature such as`png(type = "cairo")`(#74). +* `alphaMaskGrob()` can now more efficiently compute a `rasterGrob()` approximation + for `png_device` functions that support + the alpha mask feature such as`png(type = "cairo")`(#75). +* `alphaMaskGrob()` and `clippingPathGrob()` now + switch back to the previously open graphics device if + they open and close any new graphics devices. + gridpattern v1.1.1 ================== diff --git a/R/alphaMaskGrob.R b/R/alphaMaskGrob.R index 008bea5..496c90e 100644 --- a/R/alphaMaskGrob.R +++ b/R/alphaMaskGrob.R @@ -48,14 +48,14 @@ #' } #' @export alphaMaskGrob <- function(maskee, masker, - use_R4.1_masks = getOption("ggpattern_use_R4.1_masks", - getOption("ggpattern_use_R4.1_features")), - png_device = NULL, res = getOption("ggpattern_res", 72), - name = NULL, gp = gpar(), vp = NULL) { + use_R4.1_masks = getOption("ggpattern_use_R4.1_masks", + getOption("ggpattern_use_R4.1_features")), + png_device = NULL, res = getOption("ggpattern_res", 72), + name = NULL, gp = gpar(), vp = NULL) { gTree(maskee = maskee, masker = masker, use_R4.1_masks = use_R4.1_masks, res = res, png_device = png_device, - name=name, gp=gp, vp=vp, cl="alpha_mask") + name = name, gp = gp, vp = vp, cl = "alpha_mask") } # Avoid R CMD check WARNING on R 4.0 which lacks `mask` argument @@ -82,52 +82,90 @@ makeContent.alpha_mask <- function(x) { getRversion() >= '4.1.0' && requireNamespace("ragg", quietly = TRUE) && packageVersion("ragg") >= '1.2.0') { - grob <- gridpattern_mask_agg_capture(x) + grob <- gridpattern_mask_agg_capture(x$maskee, x$masker, x$res) } else { - grob <- gridpattern_mask_raster(x) + png_device <- x$png_device %||% default_png_device() + if (device_supports_masks(png_device)) { + grob <- gridpattern_mask_raster_straight(x$maskee, x$masker, x$res, png_device) + } else { + grob <- gridpattern_mask_raster_manual(x$maskee, x$masker, x$res, png_device) + } } gl <- gList(grob) setChildren(x, gl) } -gridpattern_mask_agg_capture <- function(x) { - height <- x$res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) - width <- x$res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) +device_supports_masks <- function(png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + png_file <- tempfile(fileext = ".png") + on.exit(unlink(png_file), add = TRUE) + png_device(png_file) + value <- guess_has_R4.1_features("masks") + dev.off() + value +} + +gridpattern_mask_agg_capture <- function(maskee, masker, res) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) - f_masked <- ragg::agg_capture(height = height, width = width, res = x$res, bg = "transparent") - grob <- alphaMaskGrob(x$maskee, x$masker, use_R4.1_masks = TRUE) + ragg::agg_capture(height = height, width = width, res = res, bg = "transparent") + grob <- alphaMaskGrob(maskee, masker, use_R4.1_masks = TRUE) grid.draw(grob) - raster_masked <- f_masked(native = FALSE) + raster_masked <- dev.capture(native = FALSE) dev.off() grid::rasterGrob(raster_masked) } -gridpattern_mask_raster <- function(x) { - height <- x$res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) - width <- x$res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) - png_device <- x$png_device - if (is.null(png_device)) { - if (requireNamespace("ragg", quietly = TRUE)) { - png_device <- ragg::agg_png - } else { - stopifnot(capabilities("png")) - png_device <- grDevices::png - } +default_png_device <- function() { + if (requireNamespace("ragg", quietly = TRUE)) { + ragg::agg_png + } else { + stopifnot(capabilities("png")) + grDevices::png } +} + +gridpattern_mask_raster_straight <- function(maskee, masker, res, png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) + + png_masked <- tempfile(fileext = ".png") + on.exit(unlink(png_masked), add = TRUE) + png_device(png_masked, height = height, width = width, + res = res, bg = "transparent") + grob <- alphaMaskGrob(maskee, masker, use_R4.1_masks = TRUE) + grid.draw(grob) + dev.off() + + raster_masked <- png::readPNG(png_masked, native = FALSE) + grid::rasterGrob(raster_masked) +} + +gridpattern_mask_raster_manual <- function(maskee, masker, res, png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) png_maskee <- tempfile(fileext = ".png") - on.exit(unlink(png_maskee)) + on.exit(unlink(png_maskee), add = TRUE) png_device(png_maskee, height = height, width = width, - res = x$res, bg = "transparent") - grid.draw(x$maskee) + res = res, bg = "transparent") + grid.draw(maskee) dev.off() png_masker <- tempfile(fileext = ".png") - on.exit(unlink(png_masker)) + on.exit(unlink(png_masker), add = TRUE) png_device(png_masker, height = height, width = width, - res = x$res, bg = "transparent") - grid.draw(x$masker) + res = res, bg = "transparent") + grid.draw(masker) dev.off() raster_maskee <- png::readPNG(png_maskee, native = FALSE) diff --git a/R/clippingPathGrob.R b/R/clippingPathGrob.R index 8da997a..68da7be 100644 --- a/R/clippingPathGrob.R +++ b/R/clippingPathGrob.R @@ -9,9 +9,12 @@ #' If `NULL` try to guess an appropriate choice. #' Note not all graphic devices support the grid clipping path feature #' and the grid clipping path feature does not nest. -#' @param png_device \dQuote{png} graphics device to use if `use_R4.1_clipping` is `FALSE`. -#' If `NULL` (default) will use `ragg::agg_png()` if the -#' suggested package `ragg` is available else `grDevices::png()`. +#' @param png_device \dQuote{png} graphics device to save intermediate raster data with if `use_R4.1_clipping` is `FALSE`. +#' If `NULL` and suggested package `ragg` is available +#' and versions are high enough we directly capture clipped raster via [ragg::agg_capture()]. +#' Otherwise we will use `png_device` +#' (default [ragg::agg_png()] if available else [grDevices::png()]) and [png::readPNG()] +#' to manually compute a clipped raster. #' @param res Resolution of desired `rasterGrob` in pixels per inch if `use_R4.1_clipping` is `FALSE`. #' @return A `grid` grob #' @inheritParams grid::polygonGrob @@ -41,7 +44,7 @@ clippingPathGrob <- function(clippee, clipper, gTree(clippee = clippee, clipper = clipper, use_R4.1_clipping = use_R4.1_clipping, res = res, png_device = png_device, - name=name, gp=gp, vp=vp, cl="clipping_path") + name = name, gp = gp, vp = vp, cl = "clipping_path") } #' @export @@ -61,40 +64,86 @@ makeContent.clipping_path <- function(x) { grob <- grobTree(x$clippee, vp = viewport(clip = x$clipper), name = "clip") + } else if (is.null(x$png_device) && + getRversion() >= '4.1.0' && + requireNamespace("ragg", quietly = TRUE) && + packageVersion("ragg") >= '1.2.0') { + grob <- gridpattern_clip_agg_capture(x$clippee, x$clipper, x$res) } else { - grob <- gridpattern_clip_raster(x) + png_device <- x$png_device %||% default_png_device() + if (device_supports_clipping(png_device)) { + grob <- gridpattern_clip_raster_straight(x$clippee, x$clipper, x$res, png_device) + } else { + grob <- gridpattern_clip_raster_manual(x$clippee, x$clipper, x$res, png_device) + } } gl <- gList(grob) setChildren(x, gl) } -gridpattern_clip_raster <- function(x) { - height <- x$res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) - width <- x$res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) - png_device <- x$png_device - if (is.null(png_device)) { - if (requireNamespace("ragg", quietly = TRUE)) { - png_device <- ragg::agg_png - } else { - stopifnot(capabilities("png")) - png_device <- grDevices::png - } - } +device_supports_clipping <- function(png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + png_file <- tempfile(fileext = ".png") + on.exit(unlink(png_file), add = TRUE) + png_device(png_file) + value <- guess_has_R4.1_features("clippingPaths") + dev.off() + value +} + +gridpattern_clip_agg_capture <- function(clippee, clipper, res) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) + + ragg::agg_capture(height = height, width = width, res = res, bg = "transparent") + grob <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = TRUE) + grid.draw(grob) + raster_clipped <- dev.capture(native = FALSE) + dev.off() + grid::rasterGrob(raster_clipped) +} + +gridpattern_clip_raster_straight <- function(clippee, clipper, res, png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) + + png_clipped <- tempfile(fileext = ".png") + on.exit(unlink(png_clipped), add = TRUE) + png_device(png_clipped, height = height, width = width, + res = res, bg = "transparent") + grob <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = TRUE) + grid.draw(grob) + dev.off() + + raster_clipped <- png::readPNG(png_clipped, native = FALSE) + grid::rasterGrob(raster_clipped) +} + +gridpattern_clip_raster_manual <- function(clippee, clipper, res, png_device) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) + height <- res * convertHeight(unit(1, "npc"), "in", valueOnly = TRUE) + width <- res * convertWidth(unit(1, "npc"), "in", valueOnly = TRUE) png_clippee <- tempfile(fileext = ".png") - on.exit(unlink(png_clippee)) + on.exit(unlink(png_clippee), add = TRUE) png_device(png_clippee, height = height, width = width, - res = x$res, bg = "transparent") - grid.draw(x$clippee) + res = res, bg = "transparent") + grid.draw(clippee) dev.off() png_clipper <- tempfile(fileext = ".png") - on.exit(unlink(png_clipper)) + on.exit(unlink(png_clipper), add = TRUE) png_device(png_clipper, height = height, width = width, - res = x$res, bg = "transparent") + res = res, bg = "transparent") pushViewport(viewport(gp = gpar(lwd = 0, col = NA, fill = "black"))) - grid.draw(x$clipper) + grid.draw(clipper) popViewport() dev.off() diff --git a/R/gridpattern-package.R b/R/gridpattern-package.R index 81c48f1..6f15c62 100644 --- a/R/gridpattern-package.R +++ b/R/gridpattern-package.R @@ -17,7 +17,7 @@ #' If `FALSE` do a `rasterGrob` approximation of the masked pattern. #' If `NULL` try to guess an appropriate choice.} #' \item{ggpattern_use_R4.1_patterns}{If `TRUE` use the grid pattern feature introduced in R v4.1.0. -#' Currently unused by this package.} +#' Currently only used by a couple of examples.} #' } #' Note to use the R v4.1.0 features one needs R be (at least) version 4.1 and not all graphic devices #' support any/all these features. See \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more information on these features. diff --git a/R/utils-polygon_df.R b/R/utils-polygon_df.R index fd0335b..834fa5e 100644 --- a/R/utils-polygon_df.R +++ b/R/utils-polygon_df.R @@ -148,6 +148,8 @@ get_poly_lengths <- function(sf_object) { #' #' @noRd convert_polygon_df_to_alpha_channel <- function(polygon_df, width, height) { + current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Convert the polygon to an actual grob, coloured 'black' @@ -155,6 +157,8 @@ convert_polygon_df_to_alpha_channel <- function(polygon_df, width, height) { gp <- gpar(fill = 'black') boundary_grob <- convert_polygon_df_to_polygon_grob(polygon_df, gp=gp) + # Note `ragg::agg_capture()`'s non-"native" format is a matrix of color strings + # while `png::readPNG()`'s non-"native" format is an array of numeric values #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Save the grob as an image of the given size #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -167,7 +171,7 @@ convert_polygon_df_to_alpha_channel <- function(polygon_df, width, height) { # Load the file and convert o a numeric matrix with values 0/1 depending # on whether the pixel is white or black. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - alpha_channel <- png::readPNG(png_file) + alpha_channel <- png::readPNG(png_file, native = FALSE) alpha_channel <- alpha_channel[,,1] < 0.5 storage.mode(alpha_channel) <- 'numeric' diff --git a/R/zzz.R b/R/zzz.R index 55d9a0b..c70f7de 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -14,7 +14,7 @@ img_read_memoised <- img_read #' @import grid #' @importFrom glue glue -#' @importFrom grDevices col2rgb dev.capabilities dev.off png rgb +#' @importFrom grDevices col2rgb dev.capture dev.capabilities dev.off png rgb #' @importFrom rlang %||% abort inform warn #' @importFrom utils hasName head packageVersion tail NULL diff --git a/man/clippingPathGrob.Rd b/man/clippingPathGrob.Rd index f7ca8ff..ba61fab 100644 --- a/man/clippingPathGrob.Rd +++ b/man/clippingPathGrob.Rd @@ -27,9 +27,12 @@ If \code{NULL} try to guess an appropriate choice. Note not all graphic devices support the grid clipping path feature and the grid clipping path feature does not nest.} -\item{png_device}{\dQuote{png} graphics device to use if \code{use_R4.1_clipping} is \code{FALSE}. -If \code{NULL} (default) will use \code{ragg::agg_png()} if the -suggested package \code{ragg} is available else \code{grDevices::png()}.} +\item{png_device}{\dQuote{png} graphics device to save intermediate raster data with if \code{use_R4.1_clipping} is \code{FALSE}. +If \code{NULL} and suggested package \code{ragg} is available +and versions are high enough we directly capture clipped raster via \code{\link[ragg:agg_capture]{ragg::agg_capture()}}. +Otherwise we will use \code{png_device} +(default \code{\link[ragg:agg_png]{ragg::agg_png()}} if available else \code{\link[grDevices:png]{grDevices::png()}}) and \code{\link[png:readPNG]{png::readPNG()}} +to manually compute a clipped raster.} \item{res}{Resolution of desired \code{rasterGrob} in pixels per inch if \code{use_R4.1_clipping} is \code{FALSE}.} diff --git a/man/gridpattern-package.Rd b/man/gridpattern-package.Rd index 57e7a58..0b50743 100644 --- a/man/gridpattern-package.Rd +++ b/man/gridpattern-package.Rd @@ -30,7 +30,7 @@ If \code{NULL} try to guess an appropriate choice.} If \code{FALSE} do a \code{rasterGrob} approximation of the masked pattern. If \code{NULL} try to guess an appropriate choice.} \item{ggpattern_use_R4.1_patterns}{If \code{TRUE} use the grid pattern feature introduced in R v4.1.0. -Currently unused by this package.} +Currently only used by a couple of examples.} } Note to use the R v4.1.0 features one needs R be (at least) version 4.1 and not all graphic devices support any/all these features. See \url{https://www.stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/definitions.html} for more information on these features. diff --git a/tests/figs/array/alphaMaskGrob_transparent.png b/tests/figs/array/alphaMaskGrob_feature.png similarity index 100% rename from tests/figs/array/alphaMaskGrob_transparent.png rename to tests/figs/array/alphaMaskGrob_feature.png diff --git a/tests/figs/array/alphaMaskGrob_manual.png b/tests/figs/array/alphaMaskGrob_manual.png new file mode 100644 index 0000000000000000000000000000000000000000..e41a05e2335884754a5be4cc4c7fbaa07f4b66d6 GIT binary patch literal 4304 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

PvYW0yx0Vf9CO!-5KSey5&F~BB zCx}Thzn>mrS>30Frca&lyo)G_q&b;z+C578f`62B(c{c)PHtynfSrx*RoTPOTa`3d zimly~T8lnQZOdfdGo8eXzbT*x_64+vHcW1jGSEZliRy^ z5xHbh=Xc4A4g{CmJG4jNr$z3O`vjdCt`IPe&Gt^atzk)p73d)bV&1sp#I4F~uZ={Z zB72pbF)R{mG5wDjTFUvJxmtTd&W%L&F!M!2KPOx2fq$-C$!L9r(a3*oSM#5l`02r` zv{G%QtE_V4tIs{O2s^FVuo5FKrzlbeVHrJ~Z2!1ig^+q*Q0LA%sh8k4l{~$zW-6{^ z?6@#hTu_I`KWGW>_~qK;6|N>&u*kE#Am2PHW4fbY#*~v)mOrhcb!x2jc=xsXkt4`v z<2(2bQAUfxUhS|=EmzataJ>}2Gl!9Tf0=c~aQ54B zTkgWH9Ed$~iWHJY&FCiU-oLRFlUjqny_g|2)k{;gUGh&<`4rP>P#%fB#T7;o1k9(r zG!czH^(5hlRLbB1N7_`eMnZl`_@A0_mfGCfb%(d2a)?BRA?V@P@!KOW{AV%sPdS&2l2{jqwXq+7WOe z6QmhipRr1W_j+#}YA=LtQY|5#$*8d2gAylG;-E^Syl2Bn9?Ekf;yD9I8kQGBY*Q&I z8xOFT>o7NVw`T;KxD7uVu8$cOa^%=`GJh7PZKw)vbg#VhExTFGXp(90Ll&0*iHG`O zIVt%{diGj=g%(j?6Xjv#Wxe%X>NPIL&VPvUf)VQzFZVk=8sbrtke}`gXcNawY``@S?vr>y3(QEDUJRzoo zK*wINItK6trqUGj3^JJcgYh&7pGO`oKlSy zy3{g#O3F<}uek-K98NCRK7N8?m)Dw zliK3ax%fN!aWDBI(rHV?HHv8@r>+T^O1`?+&=j&W6-?#5PVwEzY%!@@Fu%LGJF0Jx zzm|Lw71G6Z*XsH#DX@pb>(S?B8}~G}XO3&kXf5p?CZ@Z^JQ)-t&J3uK8X zior0mtl+CRuMVzvPhU(bisc}$1am(2@+85(d8y@Z*C+E%d8blmTRK;)8Yap#$y{VML{p6iG+G-I5 qh1@I2XiAFk9C4 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 H8Tx+!EYDy$ literal 0 HcmV?d00001 diff --git a/tests/figs/array/clipGrob.png b/tests/figs/array/clipGrob_manual.png similarity index 100% rename from tests/figs/array/clipGrob.png rename to tests/figs/array/clipGrob_manual.png diff --git a/tests/figs/array/clipGrob_ragg.png b/tests/figs/array/clipGrob_ragg.png new file mode 100644 index 0000000000000000000000000000000000000000..6c77feaceaf1c0e0d331fcd02bc0050efea9281e GIT binary patch literal 17473 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 B6NCT& literal 0 HcmV?d00001 diff --git a/tests/testthat/test_array.R b/tests/testthat/test_array.R index b08e8bf..c48d779 100644 --- a/tests/testthat/test_array.R +++ b/tests/testthat/test_array.R @@ -24,11 +24,10 @@ test_raster <- function(ref_png, fn, update = FALSE) { my_png <- function(f, fn) { current_dev <- grDevices::dev.cur() + if (current_dev > 1) on.exit(grDevices::dev.set(current_dev)) grDevices::png(f, type = "cairo", width = 240, height = 240) - val <- fn() + fn() grDevices::dev.off() - if (current_dev > 1) grDevices::dev.set(current_dev) - invisible(val) } test_that("array patterns works as expected", { @@ -122,26 +121,43 @@ test_that("array patterns works as expected", { y = c(y_hex_outer, y_hex_inner), id = rep(1:2, each = 7), rule = "evenodd") + + clipped <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = FALSE, + png_device = grDevices::png) + test_raster("clipGrob_cairo.png", function() grid.draw(clipped)) + + clipped <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = NULL) + test_raster("clipGrob_feature.png", function() grid.draw(clipped)) + + png_device <- default_png_device() + test_raster("clipGrob_manual.png", function() { + clipped <- gridpattern_clip_raster_manual(clippee, clipper, 72, png_device) + grid.draw(clipped) + }) + clipped <- clippingPathGrob(clippee, clipper, use_R4.1_clipping = FALSE) - test_raster("clipGrob.png", function() grid.draw(clipped)) + test_raster("clipGrob_ragg.png", function() grid.draw(clipped)) # alphaMaskGrob() - clipper <- editGrob(clipper, gp = gpar(col = NA, fill = "black")) - masked <- alphaMaskGrob(clippee, clipper, use_R4.1_masks = FALSE) - test_raster("alphaMaskGrob.png", function() grid.draw(masked)) - - clippee <- rectGrob(gp = gpar(fill = "blue", col = NA)) - clipper <- editGrob(clipper, gp = gpar(col = "black", lwd=20, fill = rgb(0, 0, 0, 0.5))) - masked <- alphaMaskGrob(clippee, clipper, use_R4.1_masks = NULL) - test_raster("alphaMaskGrob_transparent.png", function() grid.draw(masked)) - - clippee <- rectGrob(gp = gpar(fill = "blue", col = NA)) - clipper <- editGrob(clipper, gp = gpar(col = "black", lwd=20, fill = rgb(0, 0, 0, 0.5))) - bitmapType = getOption("bitmapType") - options(bitmapType = "cairo") - masked <- alphaMaskGrob(clippee, clipper, use_R4.1_masks = FALSE, png_device = grDevices::png) - test_raster("alphaMaskGrob_cairo.png", function() grid.draw(masked)) - options(bitmapType = bitmapType) + clippee2 <- rectGrob(gp = gpar(fill = "blue", col = NA)) + clipper2 <- editGrob(clipper, gp = gpar(col = NA, fill = "black")) + clipper3 <- editGrob(clipper2, gp = gpar(col = "black", lwd=20, fill = rgb(0, 0, 0, 0.5))) + + masked <- alphaMaskGrob(clippee2, clipper3, use_R4.1_masks = FALSE, png_device = grDevices::png) + test_raster("alphaMaskGrob_cairo.png", function() { + grid.draw(masked) + }) + + masked <- alphaMaskGrob(clippee2, clipper3, use_R4.1_masks = NULL) + test_raster("alphaMaskGrob_feature.png", function() grid.draw(masked)) + + test_raster("alphaMaskGrob_manual.png", function() { + masked <- gridpattern_mask_raster_manual(clippee2, clipper3, 72, png_device) + grid.draw(masked) + }) + + masked <- alphaMaskGrob(clippee, clipper2, use_R4.1_masks = FALSE) + test_raster("alphaMaskGrob_ragg.png", function() grid.draw(masked)) # ambient skip_if_not_installed("ambient")