C API: add radial, sweep, and two-point conical gradient shaders

Review URL: https://codereview.chromium.org/1263773006
This commit is contained in:
halcanary 2015-08-12 07:37:34 -07:00 committed by Commit bot
parent b427db1d45
commit 65cc3e4644
3 changed files with 230 additions and 1 deletions

View File

@ -24,7 +24,25 @@ typedef enum {
MIRROR_SK_SHADER_TILEMODE, MIRROR_SK_SHADER_TILEMODE,
} sk_shader_tilemode_t; } 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 sk_color_t colors[],
const float colorPos[], const float colorPos[],
int colorCount, int colorCount,
@ -32,6 +50,94 @@ sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
const sk_matrix_t* localMatrix); 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 SK_C_PLUS_PLUS_END_GUARD
#endif #endif

View File

@ -556,6 +556,86 @@ sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t pts[2],
return (sk_shader_t*)s; 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" #include "../../include/effects/SkBlurMaskFilter.h"

View File

@ -8,9 +8,51 @@
#include "sk_canvas.h" #include "sk_canvas.h"
#include "sk_paint.h" #include "sk_paint.h"
#include "sk_surface.h" #include "sk_surface.h"
#include "sk_shader.h"
#include "Test.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) { static void test_c(skiatest::Reporter* reporter) {
sk_colortype_t ct = sk_colortype_get_default_8888(); 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) { DEF_TEST(C_API, reporter) {
test_c(reporter); test_c(reporter);
shader_test(reporter);
} }