From a0ac963eea26e38b6918da4de2c697a96715799e Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Wed, 3 May 2017 13:07:28 -0400 Subject: [PATCH] Add a GM to exercise some complex gradient constructs Change-Id: Ic6bd68be74619fad1babbe2b969f337208e1a3b3 Reviewed-on: https://skia-review.googlesource.com/15191 Reviewed-by: Herb Derby Commit-Queue: Florin Malita --- gm/gradients.cpp | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/gm/gradients.cpp b/gm/gradients.cpp index e7a8a89..27fd0f3 100644 --- a/gm/gradients.cpp +++ b/gm/gradients.cpp @@ -937,3 +937,109 @@ DEF_SIMPLE_GM(gradient_subpixel, canvas, 500, 500) { DEF_SIMPLE_GM(gradient_subpixel_4f, canvas, 500, 500) { draw_subpixel_gradient(canvas, SkLinearGradient::kForce4fContext_PrivateFlag); } + +#include "SkPictureRecorder.h" + +static void draw_circle_shader(SkCanvas* canvas, SkScalar cx, SkScalar cy, SkScalar r, + sk_sp (*shaderFunc)()) { + SkPaint p; + p.setAntiAlias(true); + p.setShader(shaderFunc()); + canvas->drawCircle(cx, cy, r, p); + + p.setShader(nullptr); + p.setColor(SK_ColorGRAY); + p.setStyle(SkPaint::kStroke_Style); + p.setStrokeWidth(2); + canvas->drawCircle(cx, cy, r, p); +} + +DEF_SIMPLE_GM(fancy_gradients, canvas, 800, 300) { + draw_circle_shader(canvas, 150, 150, 100, []() -> sk_sp { + // Checkerboard using two linear gradients + picture shader. + SkScalar kTileSize = 80 / sqrtf(2); + SkColor colors1[] = { 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000 }; + SkColor colors2[] = { 0xff000000, 0xff000000, + 0x00000000, 0x00000000, + 0xff000000, 0xff000000 }; + SkScalar pos[] = { 0, .25f, .25f, .75f, .75f, 1 }; + static_assert(SK_ARRAY_COUNT(colors1) == SK_ARRAY_COUNT(pos), "color/pos size mismatch"); + static_assert(SK_ARRAY_COUNT(colors2) == SK_ARRAY_COUNT(pos), "color/pos size mismatch"); + + SkPictureRecorder recorder; + recorder.beginRecording(SkRect::MakeWH(kTileSize, kTileSize)); + + SkPaint p; + + SkPoint pts1[] = { { 0, 0 }, { kTileSize, kTileSize }}; + p.setShader(SkGradientShader::MakeLinear(pts1, colors1, pos, SK_ARRAY_COUNT(colors1), + SkShader::kClamp_TileMode, 0, nullptr)); + recorder.getRecordingCanvas()->drawPaint(p); + + SkPoint pts2[] = { { 0, kTileSize }, { kTileSize, 0 }}; + p.setShader(SkGradientShader::MakeLinear(pts2, colors2, pos, SK_ARRAY_COUNT(colors2), + SkShader::kClamp_TileMode, 0, nullptr)); + recorder.getRecordingCanvas()->drawPaint(p); + + SkMatrix m = SkMatrix::I(); + m.preRotate(45); + return SkShader::MakePictureShader(recorder.finishRecordingAsPicture(), + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode, &m, nullptr); + }); + + draw_circle_shader(canvas, 400, 150, 100, []() -> sk_sp { + // Checkerboard using a sweep gradient + picture shader. + SkScalar kTileSize = 80; + SkColor colors[] = { 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff, + 0xff000000, 0xff000000, + 0xffffffff, 0xffffffff }; + SkScalar pos[] = { 0, .25f, .25f, .5f, .5f, .75f, .75f, 1 }; + static_assert(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos), "color/pos size mismatch"); + + SkPaint p; + p.setShader(SkGradientShader::MakeSweep(kTileSize / 2, kTileSize / 2, + colors, pos, SK_ARRAY_COUNT(colors), 0, nullptr)); + SkPictureRecorder recorder; + recorder.beginRecording(SkRect::MakeWH(kTileSize, kTileSize))->drawPaint(p); + + return SkShader::MakePictureShader(recorder.finishRecordingAsPicture(), + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode, nullptr, nullptr); + }); + + draw_circle_shader(canvas, 650, 150, 100, []() -> sk_sp { + // Dartboard using sweep + radial. + const SkColor a = 0xffffffff; + const SkColor b = 0xff000000; + SkColor colors[] = { a, a, b, b, a, a, b, b, a, a, b, b, a, a, b, b}; + SkScalar pos[] = { 0, .125f, .125f, .25f, .25f, .375f, .375f, .5f, .5f, + .625f, .625f, .75f, .75f, .875f, .875f, 1}; + static_assert(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(pos), "color/pos size mismatch"); + + SkPoint center = { 650, 150 }; + sk_sp sweep1 = SkGradientShader::MakeSweep(center.x(), center.y(), colors, pos, + SK_ARRAY_COUNT(colors), 0, nullptr); + SkMatrix m = SkMatrix::I(); + m.preRotate(22.5f, center.x(), center.y()); + sk_sp sweep2 = SkGradientShader::MakeSweep(center.x(), center.y(), colors, pos, + SK_ARRAY_COUNT(colors), 0, &m); + + sk_sp sweep(SkShader::MakeComposeShader(sweep1, sweep2, SkBlendMode::kExclusion)); + + SkScalar radialPos[] = { 0, .02f, .02f, .04f, .04f, .08f, .08f, .16f, .16f, .31f, .31f, + .62f, .62f, 1, 1, 1 }; + static_assert(SK_ARRAY_COUNT(colors) == SK_ARRAY_COUNT(radialPos), + "color/pos size mismatch"); + + return SkShader::MakeComposeShader(sweep, + SkGradientShader::MakeRadial(center, 100, colors, + radialPos, + SK_ARRAY_COUNT(radialPos), + SkShader::kClamp_TileMode), + SkBlendMode::kExclusion); + }); +} -- 2.7.4