| # File src/library/grid/R/roundrect.R |
| # Part of the R package, https://www.R-project.org |
| # |
| # Copyright (C) 1995-2016 The R Core Team |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # A copy of the GNU General Public License is available at |
| # https://www.R-project.org/Licenses/ |
| |
| |
| # Good idea to choose r as absolute unit or "snpc" |
| roundrectGrob <- function(x=0.5, y=0.5, width=1, height=1, |
| default.units="npc", |
| r=unit(0.1, "snpc"), |
| just="centre", |
| name=NULL, gp=NULL, vp=NULL) { |
| if (!is.unit(x)) |
| x <- unit(x, default.units) |
| if (!is.unit(y)) |
| y <- unit(y, default.units) |
| if (!is.unit(width)) |
| width <- unit(width, default.units) |
| if (!is.unit(height)) |
| height <- unit(height, default.units) |
| grob(x=x, y=y, width=width, height=height, r=r, just=just, |
| name=name, gp=gp, vp=vp, cl="roundrect") |
| } |
| |
| grid.roundrect <- function(...) { |
| grid.draw(roundrectGrob(...)) |
| } |
| |
| validDetails.roundrect <- function(x) { |
| if (!is.unit(x$x) || |
| !is.unit(x$y) || |
| !is.unit(x$width) || |
| !is.unit(x$height)) |
| stop("'x', 'y', 'width', and 'height' must be units") |
| if (!is.unit(x$r)) |
| stop("'r' must be a 'unit' object") |
| valid.just(x$just) |
| # Make sure that x and y are of length 1 |
| if (length(x$x) != 1 | length(x$y) != 1 | |
| length(x$width) != 1 | length(x$height) != 1) |
| stop("'x', 'y', 'width', and 'height' must have length 1") |
| x |
| } |
| |
| makeContext.roundrect <- function(x) { |
| rrvp <- viewport(x$x, x$y, x$width, x$height, just=x$just, |
| name="rrvp") |
| if (!is.null(x$vp)) { |
| x$vp <- vpStack(x$vp, rrvp) |
| } else { |
| x$vp <- rrvp |
| } |
| x |
| } |
| |
| # x, y, is the real corner |
| roundCorner <- function(num, x, y, r) { |
| n <- 10*4 |
| t <- seq(0, 2*pi, length.out=n) |
| cost <- cos(t) |
| sint <- sin(t) |
| if (num == 1) { |
| xc <- x + r |
| yc <- y + r |
| subset <- (n/2):(3*n/4) |
| } else if (num == 2) { |
| xc <- x + r |
| yc <- y - r |
| subset <- (n/4):(n/2) |
| } else if (num == 3) { |
| xc <- x - r |
| yc <- y - r |
| subset <- 1L:(n/4) |
| } else if (num == 4) { |
| xc <- x - r |
| yc <- y + r |
| subset <- (3*n/4):n |
| } |
| list(x=xc + (cost*r)[subset], y=yc + (sint*r)[subset]) |
| } |
| |
| rrpoints <- function(x) { |
| left <- 0 |
| bottom <- 0 |
| right <- convertX(unit(1, "npc"), "inches", valueOnly=TRUE) |
| top <- convertY(unit(1, "npc"), "inches", valueOnly=TRUE) |
| r <- min(convertWidth(x$r, "inches", valueOnly=TRUE), |
| convertHeight(x$r, "inches", valueOnly=TRUE)) |
| corner1 <- roundCorner(1, left, bottom, r) |
| corner2 <- roundCorner(2, left, top, r) |
| corner3 <- roundCorner(3, right, top, r) |
| corner4 <- roundCorner(4, right, bottom, r) |
| xx <- unit(c(left + r, right - r, corner4$x, |
| right, right, corner3$x, |
| right - r, left + r, corner2$x, |
| left, left, corner1$x), |
| "inches") |
| yy <- unit(c(bottom, bottom, corner4$y, |
| bottom + r, top - r, corner3$y, |
| top, top, corner2$y, |
| top - r, bottom + r, corner1$y), |
| "inches") |
| list(x=xx, y=yy) |
| } |
| |
| makeContent.roundrect <- function(x) { |
| boundary <- rrpoints(x) |
| polygonGrob(boundary$x, boundary$y, |
| name=x$name, gp=x$gp, vp=x$vp) |
| } |
| |
| xDetails.roundrect <- function(x, theta) { |
| boundary <- rrpoints(x) |
| bounds <- grid.Call(C_locnBounds, boundary$x, boundary$y, theta) |
| if (is.null(bounds)) |
| unit(0.5, "npc") |
| else |
| unit(bounds[1L], "inches") |
| } |
| |
| yDetails.roundrect <- function(x, theta) { |
| boundary <- rrpoints(x) |
| bounds <- grid.Call(C_locnBounds, boundary$x, boundary$y, theta) |
| if (is.null(bounds)) |
| unit(0.5, "npc") |
| else |
| unit(bounds[2L], "inches") |
| } |
| |
| widthDetails.roundrect <- function(x) { |
| boundary <- rrpoints(x) |
| bounds <- grid.Call(C_locnBounds, boundary$x, boundary$y, 0) |
| if (is.null(bounds)) |
| unit(0, "inches") |
| else |
| unit(bounds[3L], "inches") |
| } |
| |
| heightDetails.roundrect <- function(x) { |
| boundary <- rrpoints(x) |
| bounds <- grid.Call(C_locnBounds, boundary$x, boundary$y, 0) |
| if (is.null(bounds)) |
| unit(0, "inches") |
| else |
| unit(bounds[4L], "inches") |
| } |
| |
| |
| |