| Index: gm/gradients.cpp
|
| diff --git a/gm/gradients.cpp b/gm/gradients.cpp
|
| index 9c4d6211b7d85b72457bf53c2a78364c8a59df58..c1847d446243b18558c7b25e0684eddfe492b0d8 100644
|
| --- a/gm/gradients.cpp
|
| +++ b/gm/gradients.cpp
|
| @@ -646,3 +646,93 @@ private:
|
| DEF_GM( return new LinearGradientTinyGM(); )
|
|
|
| }
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +struct GradRun {
|
| + SkColor fColors[4];
|
| + SkScalar fPos[4];
|
| + int fCount;
|
| +};
|
| +
|
| +#define SIZE 121
|
| +
|
| +static SkShader* make_linear(const GradRun& run, SkShader::TileMode mode) {
|
| + const SkPoint pts[] { { 30, 30 }, { SIZE - 30, SIZE - 30 } };
|
| + return SkGradientShader::CreateLinear(pts, run.fColors, run.fPos, run.fCount, mode);
|
| +}
|
| +
|
| +static SkShader* make_radial(const GradRun& run, SkShader::TileMode mode) {
|
| + const SkScalar half = SIZE * 0.5f;
|
| + return SkGradientShader::CreateRadial({half,half}, half - 10,
|
| + run.fColors, run.fPos, run.fCount, mode);
|
| +}
|
| +
|
| +static SkShader* make_conical(const GradRun& run, SkShader::TileMode mode) {
|
| + const SkScalar half = SIZE * 0.5f;
|
| + const SkPoint center { half, half };
|
| + return SkGradientShader::CreateTwoPointConical(center, 20, center, half - 10,
|
| + run.fColors, run.fPos, run.fCount, mode);
|
| +}
|
| +
|
| +static SkShader* make_sweep(const GradRun& run, SkShader::TileMode) {
|
| + const SkScalar half = SIZE * 0.5f;
|
| + return SkGradientShader::CreateSweep(half, half, run.fColors, run.fPos, run.fCount);
|
| +}
|
| +
|
| +/*
|
| + * Exercise duplicate color-stops, at the ends, and in the middle
|
| + *
|
| + * At the time of this writing, only Linear correctly deals with duplicates at the ends,
|
| + * and then only correctly on CPU backend.
|
| + */
|
| +DEF_SIMPLE_GM(gradients_dup_color_stops, canvas, 704, 564) {
|
| + const SkColor preColor = 0xFFFF0000; // clamp color before start
|
| + const SkColor postColor = 0xFF0000FF; // clamp color after end
|
| + const SkColor color0 = 0xFF000000;
|
| + const SkColor color1 = 0xFF00FF00;
|
| + const SkColor badColor = 0xFF3388BB; // should never be seen, fills out fixed-size array
|
| +
|
| + const GradRun runs[] = {
|
| + { { color0, color1, badColor, badColor },
|
| + { 0, 1, -1, -1 },
|
| + 2,
|
| + },
|
| + { { preColor, color0, color1, badColor },
|
| + { 0, 0, 1, -1 },
|
| + 3,
|
| + },
|
| + { { color0, color1, postColor, badColor },
|
| + { 0, 1, 1, -1 },
|
| + 3,
|
| + },
|
| + { { preColor, color0, color1, postColor },
|
| + { 0, 0, 1, 1 },
|
| + 4,
|
| + },
|
| + { { color0, color0, color1, color1 },
|
| + { 0, 0.5f, 0.5f, 1 },
|
| + 4,
|
| + },
|
| + };
|
| + SkShader* (*factories[])(const GradRun&, SkShader::TileMode) {
|
| + make_linear, make_radial, make_conical, make_sweep
|
| + };
|
| +
|
| + const SkRect rect = SkRect::MakeWH(SIZE, SIZE);
|
| + const SkScalar dx = SIZE + 20;
|
| + const SkScalar dy = SIZE + 20;
|
| + const SkShader::TileMode mode = SkShader::kClamp_TileMode;
|
| +
|
| + SkPaint paint;
|
| + canvas->translate(10, 10 - dy);
|
| + for (auto factory : factories) {
|
| + canvas->translate(0, dy);
|
| + SkAutoCanvasRestore acr(canvas, true);
|
| + for (const auto& run : runs) {
|
| + paint.setShader(factory(run, mode))->unref();
|
| + canvas->drawRect(rect, paint);
|
| + canvas->translate(dx, 0);
|
| + }
|
| + }
|
| +}
|
|
|