aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar halcanary <halcanary@google.com>2015-08-12 07:37:34 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-12 07:37:34 -0700
commit65cc3e46445a26aadd21f111e0d69fd18fd8aa11 (patch)
tree1186bb9798c95d314079d34efe46c88df109cfe8
parentb427db1d457a083f2652756a453fbb91bc6a7447 (diff)
C API: add radial, sweep, and two-point conical gradient shaders
-rw-r--r--include/c/sk_shader.h108
-rw-r--r--src/c/sk_surface.cpp80
-rw-r--r--tests/CTest.cpp43
3 files changed, 230 insertions, 1 deletions
diff --git a/include/c/sk_shader.h b/include/c/sk_shader.h
index 9f83ff0415..702cda7fd4 100644
--- a/include/c/sk_shader.h
+++ b/include/c/sk_shader.h
@@ -24,13 +24,119 @@ typedef enum {
MIRROR_SK_SHADER_TILEMODE,
} sk_shader_tilemode_t;
-sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
+/**
+ Returns a shader that generates a linear gradient between the two
+ specified points.
+
+ @param points The start and end points for the gradient.
+ @param colors The array[count] of colors, to be distributed between
+ the two points
+ @param colorPos May be NULL. array[count] of SkScalars, or NULL, of
+ the relative position of each corresponding color
+ in the colors array. If this is NULL, the the
+ colors are distributed evenly between the start
+ and end point. If this is not null, the values
+ must begin with 0, end with 1.0, and intermediate
+ values must be strictly increasing.
+ @param colorCount Must be >=2. The number of colors (and pos if not
+ NULL) entries.
+ @param mode The tiling mode
+*/
+sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2],
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ sk_shader_tilemode_t tileMode,
+ const sk_matrix_t* localMatrix);
+
+
+/**
+ Returns a shader that generates a radial gradient given the center
+ and radius.
+
+ @param center The center of the circle for this gradient
+ @param radius Must be positive. The radius of the circle for this
+ gradient
+ @param colors The array[count] of colors, to be distributed
+ between the center and edge of the circle
+ @param colorPos May be NULL. The array[count] of the relative
+ position of each corresponding color in the colors
+ array. If this is NULL, the the colors are
+ distributed evenly between the center and edge of
+ the circle. If this is not null, the values must
+ begin with 0, end with 1.0, and intermediate
+ values must be strictly increasing.
+ @param count Must be >= 2. The number of colors (and pos if not
+ NULL) entries
+ @param tileMode The tiling mode
+ @param localMatrix May be NULL
+*/
+sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* center,
+ float radius,
const sk_color_t colors[],
const float colorPos[],
int colorCount,
sk_shader_tilemode_t tileMode,
const sk_matrix_t* localMatrix);
+/**
+ Returns a shader that generates a sweep gradient given a center.
+
+ @param center The coordinates of the center of the sweep
+ @param colors The array[count] of colors, to be distributed around
+ the center.
+ @param colorPos May be NULL. The array[count] of the relative
+ position of each corresponding color in the colors
+ array. If this is NULL, the the colors are
+ distributed evenly between the center and edge of
+ the circle. If this is not null, the values must
+ begin with 0, end with 1.0, and intermediate
+ values must be strictly increasing.
+ @param colorCount Must be >= 2. The number of colors (and pos if
+ not NULL) entries
+ @param localMatrix May be NULL
+*/
+sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* center,
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ const sk_matrix_t* localMatrix);
+
+/**
+ Returns a shader that generates a conical gradient given two circles, or
+ returns NULL if the inputs are invalid. The gradient interprets the
+ two circles according to the following HTML spec.
+ http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
+
+ Returns a shader that generates a sweep gradient given a center.
+
+ @param start, startRadius Defines the first circle.
+ @param end, endRadius Defines the first circle.
+ @param colors The array[count] of colors, to be distributed between
+ the two circles.
+ @param colorPos May be NULL. The array[count] of the relative
+ position of each corresponding color in the colors
+ array. If this is NULL, the the colors are
+ distributed evenly between the two circles. If
+ this is not null, the values must begin with 0,
+ end with 1.0, and intermediate values must be
+ strictly increasing.
+ @param colorCount Must be >= 2. The number of colors (and pos if
+ not NULL) entries
+ @param tileMode The tiling mode
+ @param localMatrix May be NULL
+
+*/
+sk_shader_t* sk_shader_new_two_point_conical_gradient(
+ const sk_point_t* start,
+ float startRadius,
+ const sk_point_t* end,
+ float endRadius,
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ sk_shader_tilemode_t tileMode,
+ const sk_matrix_t* localMatrix);
SK_C_PLUS_PLUS_END_GUARD
diff --git a/src/c/sk_surface.cpp b/src/c/sk_surface.cpp
index 84a9c541c2..ccab9dfa1a 100644
--- a/src/c/sk_surface.cpp
+++ b/src/c/sk_surface.cpp
@@ -556,6 +556,86 @@ sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
return (sk_shader_t*)s;
}
+static const SkPoint& to_skpoint(const sk_point_t& p) {
+ return reinterpret_cast<const SkPoint&>(p);
+}
+
+sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* ccenter,
+ float radius,
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ sk_shader_tilemode_t cmode,
+ const sk_matrix_t* cmatrix) {
+ SkShader::TileMode mode;
+ if (!from_c_tilemode(cmode, &mode)) {
+ return NULL;
+ }
+ SkMatrix matrix;
+ if (cmatrix) {
+ from_c_matrix(cmatrix, &matrix);
+ } else {
+ matrix.setIdentity();
+ }
+ SkPoint center = to_skpoint(*ccenter);
+ SkShader* s = SkGradientShader::CreateRadial(
+ center, (SkScalar)radius,
+ reinterpret_cast<const SkColor*>(colors),
+ reinterpret_cast<const SkScalar*>(colorPos),
+ colorCount, mode, 0, &matrix);
+ return (sk_shader_t*)s;
+}
+
+sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* ccenter,
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ const sk_matrix_t* cmatrix) {
+ SkMatrix matrix;
+ if (cmatrix) {
+ from_c_matrix(cmatrix, &matrix);
+ } else {
+ matrix.setIdentity();
+ }
+ SkShader* s = SkGradientShader::CreateSweep(
+ (SkScalar)(ccenter->x),
+ (SkScalar)(ccenter->y),
+ reinterpret_cast<const SkColor*>(colors),
+ reinterpret_cast<const SkScalar*>(colorPos),
+ colorCount, 0, &matrix);
+ return (sk_shader_t*)s;
+}
+
+sk_shader_t* sk_shader_new_two_point_conical_gradient(const sk_point_t* start,
+ float startRadius,
+ const sk_point_t* end,
+ float endRadius,
+ const sk_color_t colors[],
+ const float colorPos[],
+ int colorCount,
+ sk_shader_tilemode_t cmode,
+ const sk_matrix_t* cmatrix) {
+ SkShader::TileMode mode;
+ if (!from_c_tilemode(cmode, &mode)) {
+ return NULL;
+ }
+ SkMatrix matrix;
+ if (cmatrix) {
+ from_c_matrix(cmatrix, &matrix);
+ } else {
+ matrix.setIdentity();
+ }
+ SkPoint skstart = to_skpoint(*start);
+ SkPoint skend = to_skpoint(*end);
+ SkShader* s = SkGradientShader::CreateTwoPointConical(
+ skstart, (SkScalar)startRadius,
+ skend, (SkScalar)endRadius,
+ reinterpret_cast<const SkColor*>(colors),
+ reinterpret_cast<const SkScalar*>(colorPos),
+ colorCount, mode, 0, &matrix);
+ return (sk_shader_t*)s;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
#include "../../include/effects/SkBlurMaskFilter.h"
diff --git a/tests/CTest.cpp b/tests/CTest.cpp
index acab4bb11b..4cc8cd6666 100644
--- a/tests/CTest.cpp
+++ b/tests/CTest.cpp
@@ -8,9 +8,51 @@
#include "sk_canvas.h"
#include "sk_paint.h"
#include "sk_surface.h"
+#include "sk_shader.h"
#include "Test.h"
+
+static void shader_test(skiatest::Reporter* reporter) {
+ sk_imageinfo_t info =
+ {64, 64, sk_colortype_get_default_8888(), PREMUL_SK_ALPHATYPE};
+ sk_surface_t* surface = sk_surface_new_raster(&info, NULL);
+ sk_canvas_t* canvas = sk_surface_get_canvas(surface);
+ sk_paint_t* paint = sk_paint_new();
+
+ sk_shader_tilemode_t tilemode = CLAMP_SK_SHADER_TILEMODE;
+ sk_point_t point = {0.0f, 0.0f};
+ sk_point_t point2 = {30.0f, 40.0f};
+ sk_color_t colors[] = {
+ (sk_color_t)sk_color_set_argb(0xFF, 0x00, 0x00, 0xFF),
+ (sk_color_t)sk_color_set_argb(0xFF, 0x00, 0xFF, 0x00)
+ };
+ sk_shader_t* shader;
+
+ shader = sk_shader_new_radial_gradient(
+ &point, 1.0f, colors, NULL, 2, tilemode, NULL);
+ REPORTER_ASSERT(reporter, shader != NULL);
+ sk_paint_set_shader(paint, shader);
+ sk_shader_unref(shader);
+ sk_canvas_draw_paint(canvas, paint);
+
+ shader = sk_shader_new_sweep_gradient(&point, colors, NULL, 2, NULL);
+ REPORTER_ASSERT(reporter, shader != NULL);
+ sk_paint_set_shader(paint, shader);
+ sk_shader_unref(shader);
+ sk_canvas_draw_paint(canvas, paint);
+
+ shader = sk_shader_new_two_point_conical_gradient(
+ &point, 10.0f, &point2, 50.0f, colors, NULL, 2, tilemode, NULL);
+ REPORTER_ASSERT(reporter, shader != NULL);
+ sk_paint_set_shader(paint, shader);
+ sk_shader_unref(shader);
+ sk_canvas_draw_paint(canvas, paint);
+
+ sk_paint_delete(paint);
+ sk_surface_unref(surface);
+}
+
static void test_c(skiatest::Reporter* reporter) {
sk_colortype_t ct = sk_colortype_get_default_8888();
@@ -43,4 +85,5 @@ static void test_c(skiatest::Reporter* reporter) {
DEF_TEST(C_API, reporter) {
test_c(reporter);
+ shader_test(reporter);
}