skia2/gm/gradients_degenerate.cpp
Ben Wagner 7fde8e1728 IWYU for gms.
This almost gets gms to be iwyu clean. The last bit is around gm.cpp
and the tracing framework and its use of atomic. Will also need a way
of keeping things from regressing, which is difficult due to needing to
do this outside-in.

Change-Id: I1393531e99da8b0f1a29f55c53c86d53f459af7d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/211593
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
2019-05-02 17:48:53 +00:00

157 lines
5.3 KiB
C++

/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
// NOTE: The positions define hardstops for the red and green borders. For the repeating degenerate
// gradients, that means the red and green are never visible, so the average color used should only
// be based off of the white, blue, black blend.
static const SkColor COLORS[] = { SK_ColorRED, SK_ColorWHITE, SK_ColorBLUE,
SK_ColorBLACK, SK_ColorGREEN };
static const SkScalar POS[] = { 0.0, 0.0, 0.5, 1.0, 1.0 };
static const int COLOR_CT = SK_ARRAY_COUNT(COLORS);
static const SkTileMode TILE_MODES[] = { SkTileMode::kDecal,
SkTileMode::kRepeat,
SkTileMode::kMirror,
SkTileMode::kClamp };
static const char* TILE_NAMES[] = { "decal", "repeat", "mirror", "clamp" };
static const int TILE_MODE_CT = SK_ARRAY_COUNT(TILE_MODES);
static constexpr int TILE_SIZE = 100;
static constexpr int TILE_GAP = 10;
static const SkPoint CENTER = SkPoint::Make(TILE_SIZE / 2, TILE_SIZE / 2);
typedef sk_sp<SkShader> (*GradientFactory)(SkTileMode tm);
static void draw_tile_header(SkCanvas* canvas) {
canvas->save();
for (int i = 0; i < TILE_MODE_CT; ++i) {
canvas->drawString(TILE_NAMES[i], 0, 0, SkFont(), SkPaint());
canvas->translate(TILE_SIZE + TILE_GAP, 0);
}
canvas->restore();
// Now adjust to start at rows below the header
canvas->translate(0, 2 * TILE_GAP);
}
static void draw_row(SkCanvas* canvas, const char* desc, GradientFactory factory) {
canvas->save();
SkPaint text;
text.setAntiAlias(true);
canvas->translate(0, TILE_GAP);
canvas->drawString(desc, 0, 0, SkFont(), text);
canvas->translate(0, TILE_GAP);
SkPaint paint;
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStrokeAndFill_Style);
paint.setStrokeWidth(2.0f);
for (int i = 0; i < TILE_MODE_CT; ++i) {
paint.setShader(factory(TILE_MODES[i]));
canvas->drawRect(SkRect::MakeWH(TILE_SIZE, TILE_SIZE), paint);
canvas->translate(TILE_SIZE + TILE_GAP, 0);
}
canvas->restore();
// Now adjust to start the next row below this one (1 gap for text and 2 gap for margin)
canvas->translate(0, 3 * TILE_GAP + TILE_SIZE);
}
static sk_sp<SkShader> make_linear(SkTileMode mode) {
// Same position
SkPoint pts[2] = {CENTER, CENTER};
return SkGradientShader::MakeLinear(pts, COLORS, POS, COLOR_CT, mode);
}
static sk_sp<SkShader> make_radial(SkTileMode mode) {
// Radius = 0
return SkGradientShader::MakeRadial(CENTER, 0.0, COLORS, POS, COLOR_CT, mode);
}
static sk_sp<SkShader> make_sweep(SkTileMode mode) {
// Start and end angles at 45
static constexpr SkScalar SWEEP_ANG = 45.0;
return SkGradientShader::MakeSweep(CENTER.fX, CENTER.fY, COLORS, POS, COLOR_CT, mode,
SWEEP_ANG, SWEEP_ANG, 0, nullptr);
}
static sk_sp<SkShader> make_sweep_zero_ang(SkTileMode mode) {
// Start and end angles at 0
return SkGradientShader::MakeSweep(CENTER.fX, CENTER.fY, COLORS, POS, COLOR_CT, mode,
0.0, 0.0, 0, nullptr);
}
static sk_sp<SkShader> make_2pt_conic(SkTileMode mode) {
// Start and end radius = TILE_SIZE, same position
return SkGradientShader::MakeTwoPointConical(CENTER, TILE_SIZE / 2, CENTER, TILE_SIZE / 2,
COLORS, POS, COLOR_CT, mode);
}
static sk_sp<SkShader> make_2pt_conic_zero_rad(SkTileMode mode) {
// Start and end radius = 0, same position
return SkGradientShader::MakeTwoPointConical(CENTER, 0.0, CENTER, 0.0, COLORS, POS,
COLOR_CT, mode);
}
class DegenerateGradientGM : public skiagm::GM {
public:
DegenerateGradientGM() {
}
protected:
SkString onShortName() override {
return SkString("degenerate_gradients");
}
SkISize onISize() override {
return SkISize::Make(800, 800);
}
void onDraw(SkCanvas* canvas) override {
canvas->translate(3 * TILE_GAP, 3 * TILE_GAP);
draw_tile_header(canvas);
draw_row(canvas, "linear: empty, blue, blue, green", make_linear);
draw_row(canvas, "radial: empty, blue, blue, green", make_radial);
draw_row(canvas, "sweep-0: empty, blue, blue, green", make_sweep_zero_ang);
draw_row(canvas, "sweep-45: empty, blue, blue, red 45 degree sector then green",
make_sweep);
draw_row(canvas, "2pt-conic-0: empty, blue, blue, green", make_2pt_conic_zero_rad);
draw_row(canvas, "2pt-conic-1: empty, blue, blue, full red circle on green",
make_2pt_conic);
}
private:
typedef skiagm::GM INHERITED;
};
DEF_GM(return new DegenerateGradientGM;)