skia2/gm/hardstop_gradients.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

175 lines
5.7 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
* This GM presents a variety of different gradients with different
* tile modes. Each entry in the table is a rectangle with a linear
* gradient that spans from its left edge to its right edge. The rows
* in the table represent different color/position configurations,
* while the columns in the table represent different tile modes. In
* order to highlight the differences between tile modes, the gradient
* starts and ends at 30 pixel inset from either side of the rectangle.
*
* | Clamp Repeat Mirror
* _____________________________|___________________________________________
* 2-color | rect00 rect01 rect02
* 3-color even | rect10 rect11 rect12
* 3-color texture | rect20 rect21 rect22
* 5-color hard stop | rect30 rect31 rect32
* 4-color hard stop centered | rect40 rect41 rect42
* 3-color hard stop 001 | rect50 rect51 rect52
* 3-color hard stop 011 | rect60 rect61 rect62
* 4-color hard stop off-center | rect70 rect71 rect72
*
* The first three rows are cases covered by pre-hard-stop code; simple
* 2-color gradients, 3-color gradients with the middle color centered,
* and general gradients that are rendered from a texture atlas.
*
* The next four rows all deal with hard stop gradients. The fourth row
* is a generic hard stop gradient, while the three subsequent rows deal
* with special cases of hard stop gradients; centered hard stop gradients
* (with t-values 0, 0.5, 0.5, 1), and two edge cases (with t-values
* 0, 0, 1 and 0, 1, 1). The final row has a single off-center hard stop.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.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/effects/SkGradientShader.h"
const int WIDTH = 500;
const int HEIGHT = 500;
const int NUM_ROWS = 8;
const int NUM_COLS = 3;
const int CELL_WIDTH = WIDTH / NUM_COLS;
const int CELL_HEIGHT = HEIGHT / NUM_ROWS;
const int PAD_WIDTH = 3;
const int PAD_HEIGHT = 3;
const int RECT_WIDTH = CELL_WIDTH - (2 * PAD_WIDTH);
const int RECT_HEIGHT = CELL_HEIGHT - (2 * PAD_HEIGHT);
static void shade_rect(SkCanvas* canvas, sk_sp<SkShader> shader, int cellRow, int cellCol) {
SkPaint paint;
paint.setShader(shader);
SkRect rect = SkRect::MakeXYWH(SkIntToScalar(cellCol * CELL_WIDTH + PAD_WIDTH),
SkIntToScalar(cellRow * CELL_HEIGHT + PAD_HEIGHT),
SkIntToScalar(RECT_WIDTH),
SkIntToScalar(RECT_HEIGHT));
canvas->drawRect(rect, paint);
}
static void create_gradient_points(int cellRow, int cellCol, SkPoint points[2]) {
const int X_OFFSET = 30;
auto x0 = SkIntToScalar(cellCol * CELL_WIDTH + PAD_WIDTH + X_OFFSET);
auto x1 = SkIntToScalar((cellCol+1) * CELL_WIDTH - PAD_WIDTH - X_OFFSET);
auto y = SkIntToScalar(cellRow * CELL_HEIGHT + PAD_HEIGHT + RECT_HEIGHT/2);
points[0] = SkPoint::Make(x0, y);
points[1] = SkPoint::Make(x1, y);
}
class HardstopGradientShaderGM : public skiagm::GM {
public:
HardstopGradientShaderGM() {
}
protected:
SkString onShortName() override {
return SkString("hardstop_gradients");
}
SkISize onISize() override {
return SkISize::Make(512, 512);
}
void onDraw(SkCanvas* canvas) override {
SkPoint points[2];
SkColor colors[] = {
SK_ColorRED,
SK_ColorGREEN,
SK_ColorBLUE,
SK_ColorYELLOW,
SK_ColorMAGENTA,
};
SkScalar row3[] = {0.00f, 0.25f, 1.00f};
SkScalar row4[] = {0.00f, 0.25f, 0.50f, 0.50f, 1.00f};
SkScalar row5[] = {0.00f, 0.50f, 0.50f, 1.00f};
SkScalar row6[] = {0.00f, 0.00f, 1.00f};
SkScalar row7[] = {0.00f, 1.00f, 1.00f};
SkScalar row8[] = {0.00f, 0.30f, 0.30f, 1.00f};
SkScalar* positions[NUM_ROWS] = {
nullptr,
nullptr,
row3,
row4,
row5,
row6,
row7,
row8,
};
int numGradientColors[NUM_ROWS] = {
2,
3,
3,
5,
4,
3,
3,
4,
};
SkTileMode tilemodes[NUM_COLS] = {
SkTileMode::kClamp,
SkTileMode::kRepeat,
SkTileMode::kMirror,
};
for (int cellRow = 0; cellRow < NUM_ROWS; cellRow++) {
for (int cellCol = 0; cellCol < NUM_COLS; cellCol++) {
create_gradient_points(cellRow, cellCol, points);
auto shader = SkGradientShader::MakeLinear(
points,
colors,
positions[cellRow],
numGradientColors[cellRow],
tilemodes[cellCol],
0,
nullptr);
shade_rect(canvas, shader, cellRow, cellCol);
}
}
}
private:
typedef skiagm::GM INHERITED;
};
DEF_GM(return new HardstopGradientShaderGM;)