| /* |
| * R : A Computer Language for Statistical Data Analysis |
| * Copyright (C) 2019 The R Foundation |
| * |
| * 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. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, a copy is available at |
| * https://www.R-project.org/Licenses/ |
| */ |
| |
| /* This should be regarded as part of the graphics engine */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <Defn.h> |
| #include <R_ext/GraphicsEngine.h> |
| |
| /* |
| * C API for graphics devices to interrogate gradient SEXPs |
| * |
| * MUST match R structures in ../library/grDevices/R/patterns.R |
| */ |
| |
| Rboolean R_GE_isPattern(SEXP x) { |
| return Rf_inherits(x, "Pattern"); |
| } |
| |
| /* Pattern type is always component 0 */ |
| int R_GE_patternType(SEXP pattern) |
| { |
| return INTEGER(VECTOR_ELT(pattern, 0))[0]; |
| } |
| |
| /* Linear gradients */ |
| #define linear_gradient_x1 1 |
| #define linear_gradient_y1 2 |
| #define linear_gradient_x2 3 |
| #define linear_gradient_y2 4 |
| #define linear_gradient_stops 5 |
| #define linear_gradient_colours 6 |
| #define linear_gradient_extend 7 |
| |
| #define checkLinearGradient() \ |
| if (!(R_GE_patternType(pattern) == R_GE_linearGradientPattern)) \ |
| error(_("pattern is not a linear gradient")) |
| |
| double R_GE_linearGradientX1(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return REAL(VECTOR_ELT(pattern, linear_gradient_x1))[0]; |
| } |
| |
| double R_GE_linearGradientY1(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return REAL(VECTOR_ELT(pattern, linear_gradient_y1))[0]; |
| } |
| |
| double R_GE_linearGradientX2(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return REAL(VECTOR_ELT(pattern, linear_gradient_x2))[0]; |
| } |
| |
| double R_GE_linearGradientY2(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return REAL(VECTOR_ELT(pattern, linear_gradient_y2))[0]; |
| } |
| |
| int R_GE_linearGradientNumStops(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return LENGTH(VECTOR_ELT(pattern, linear_gradient_stops)); |
| } |
| |
| double R_GE_linearGradientStop(SEXP pattern, int i) |
| { |
| checkLinearGradient(); |
| return REAL(VECTOR_ELT(pattern, linear_gradient_stops))[i]; |
| } |
| |
| rcolor R_GE_linearGradientColour(SEXP pattern, int i) |
| { |
| checkLinearGradient(); |
| return RGBpar(VECTOR_ELT(pattern, linear_gradient_colours), i); |
| } |
| |
| int R_GE_linearGradientExtend(SEXP pattern) |
| { |
| checkLinearGradient(); |
| return INTEGER(VECTOR_ELT(pattern, linear_gradient_extend))[0]; |
| } |
| |
| /* Radial gradients */ |
| #define radial_gradient_cx1 1 |
| #define radial_gradient_cy1 2 |
| #define radial_gradient_r1 3 |
| #define radial_gradient_cx2 4 |
| #define radial_gradient_cy2 5 |
| #define radial_gradient_r2 6 |
| #define radial_gradient_stops 7 |
| #define radial_gradient_colours 8 |
| #define radial_gradient_extend 9 |
| |
| #define checkRadialGradient() \ |
| if (!(R_GE_patternType(pattern) == R_GE_radialGradientPattern)) \ |
| error(_("pattern is not a radial gradient")) |
| |
| double R_GE_radialGradientCX1(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_cx1))[0]; |
| } |
| |
| double R_GE_radialGradientCY1(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_cy1))[0]; |
| } |
| |
| double R_GE_radialGradientR1(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_r1))[0]; |
| } |
| |
| double R_GE_radialGradientCX2(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_cx2))[0]; |
| } |
| |
| double R_GE_radialGradientCY2(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_cy2))[0]; |
| } |
| |
| double R_GE_radialGradientR2(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_r2))[0]; |
| } |
| |
| int R_GE_radialGradientNumStops(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return LENGTH(VECTOR_ELT(pattern, radial_gradient_stops)); |
| } |
| |
| double R_GE_radialGradientStop(SEXP pattern, int i) |
| { |
| checkRadialGradient(); |
| return REAL(VECTOR_ELT(pattern, radial_gradient_stops))[i]; |
| } |
| |
| rcolor R_GE_radialGradientColour(SEXP pattern, int i) |
| { |
| checkRadialGradient(); |
| return RGBpar(VECTOR_ELT(pattern, radial_gradient_colours), i); |
| } |
| |
| int R_GE_radialGradientExtend(SEXP pattern) |
| { |
| checkRadialGradient(); |
| return INTEGER(VECTOR_ELT(pattern, radial_gradient_extend))[0]; |
| } |
| |
| /* Tiling patterns */ |
| #define tiling_pattern_function 1 |
| #define tiling_pattern_x 2 |
| #define tiling_pattern_y 3 |
| #define tiling_pattern_width 4 |
| #define tiling_pattern_height 5 |
| #define tiling_pattern_extend 6 |
| |
| #define checkTilingPattern() \ |
| if (!(R_GE_patternType(pattern) == R_GE_tilingPattern)) \ |
| error(_("pattern is not a tiling pattern")) |
| |
| SEXP R_GE_tilingPatternFunction(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return VECTOR_ELT(pattern, tiling_pattern_function); |
| } |
| |
| double R_GE_tilingPatternX(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return REAL(VECTOR_ELT(pattern, tiling_pattern_x))[0]; |
| } |
| |
| double R_GE_tilingPatternY(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return REAL(VECTOR_ELT(pattern, tiling_pattern_y))[0]; |
| } |
| |
| double R_GE_tilingPatternWidth(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return REAL(VECTOR_ELT(pattern, tiling_pattern_width))[0]; |
| } |
| |
| double R_GE_tilingPatternHeight(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return REAL(VECTOR_ELT(pattern, tiling_pattern_height))[0]; |
| } |
| |
| int R_GE_tilingPatternExtend(SEXP pattern) |
| { |
| checkTilingPattern(); |
| return INTEGER(VECTOR_ELT(pattern, tiling_pattern_extend))[0]; |
| } |
| |
| |