1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 /* 9 * This GM presents a variety of different gradients with different 10 * tile modes. Each entry in the table is a rectangle with a linear 11 * gradient that spans from its left edge to its right edge. The rows 12 * in the table represent different color/position configurations, 13 * while the columns in the table represent different tile modes. In 14 * order to highlight the differences between tile modes, the gradient 15 * starts and ends at 30 pixel inset from either side of the rectangle. 16 * 17 * | Clamp Repeat Mirror 18 * _____________________________|___________________________________________ 19 * 2-color | rect00 rect01 rect02 20 * 3-color even | rect10 rect11 rect12 21 * 3-color texture | rect20 rect21 rect22 22 * 5-color hard stop | rect30 rect31 rect32 23 * 4-color hard stop centered | rect40 rect41 rect42 24 * 3-color hard stop 001 | rect50 rect51 rect52 25 * 3-color hard stop 011 | rect60 rect61 rect62 26 * 4-color hard stop off-center | rect70 rect71 rect72 27 * 28 * The first three rows are cases covered by pre-hard-stop code; simple 29 * 2-color gradients, 3-color gradients with the middle color centered, 30 * and general gradients that are rendered from a texture atlas. 31 * 32 * The next four rows all deal with hard stop gradients. The fourth row 33 * is a generic hard stop gradient, while the three subsequent rows deal 34 * with special cases of hard stop gradients; centered hard stop gradients 35 * (with t-values 0, 0.5, 0.5, 1), and two edge cases (with t-values 36 * 0, 0, 1 and 0, 1, 1). The final row has a single off-center hard stop. 37 */ 38 39 #include "gm.h" 40 41 #include "SkGradientShader.h" 42 43 const int WIDTH = 500; 44 const int HEIGHT = 500; 45 46 const int NUM_ROWS = 8; 47 const int NUM_COLS = 3; 48 49 const int CELL_WIDTH = WIDTH / NUM_COLS; 50 const int CELL_HEIGHT = HEIGHT / NUM_ROWS; 51 52 const int PAD_WIDTH = 3; 53 const int PAD_HEIGHT = 3; 54 55 const int RECT_WIDTH = CELL_WIDTH - (2 * PAD_WIDTH); 56 const int RECT_HEIGHT = CELL_HEIGHT - (2 * PAD_HEIGHT); 57 58 static void shade_rect(SkCanvas* canvas, sk_sp<SkShader> shader, int cellRow, int cellCol) { 59 SkPaint paint; 60 paint.setShader(shader); 61 62 SkRect rect = SkRect::MakeXYWH(SkIntToScalar(cellCol * CELL_WIDTH + PAD_WIDTH), 63 SkIntToScalar(cellRow * CELL_HEIGHT + PAD_HEIGHT), 64 SkIntToScalar(RECT_WIDTH), 65 SkIntToScalar(RECT_HEIGHT)); 66 67 canvas->drawRect(rect, paint); 68 } 69 70 static void create_gradient_points(int cellRow, int cellCol, SkPoint points[2]) { 71 const int X_OFFSET = 30; 72 73 auto x0 = SkIntToScalar(cellCol * CELL_WIDTH + PAD_WIDTH + X_OFFSET); 74 auto x1 = SkIntToScalar((cellCol+1) * CELL_WIDTH - PAD_WIDTH - X_OFFSET); 75 auto y = SkIntToScalar(cellRow * CELL_HEIGHT + PAD_HEIGHT + RECT_HEIGHT/2); 76 77 points[0] = SkPoint::Make(x0, y); 78 points[1] = SkPoint::Make(x1, y); 79 } 80 81 class HardstopGradientShaderGM : public skiagm::GM { 82 public: 83 HardstopGradientShaderGM() { 84 85 } 86 87 protected: 88 SkString onShortName() override { 89 return SkString("hardstop_gradients"); 90 } 91 92 SkISize onISize() override { 93 return SkISize::Make(512, 512); 94 } 95 96 void onDraw(SkCanvas* canvas) override { 97 SkPoint points[2]; 98 99 SkColor colors[] = { 100 SK_ColorRED, 101 SK_ColorGREEN, 102 SK_ColorBLUE, 103 SK_ColorYELLOW, 104 SK_ColorMAGENTA, 105 }; 106 107 SkScalar row3[] = {0.00f, 0.25f, 1.00f}; 108 SkScalar row4[] = {0.00f, 0.25f, 0.50f, 0.50f, 1.00f}; 109 SkScalar row5[] = {0.00f, 0.50f, 0.50f, 1.00f}; 110 SkScalar row6[] = {0.00f, 0.00f, 1.00f}; 111 SkScalar row7[] = {0.00f, 1.00f, 1.00f}; 112 SkScalar row8[] = {0.00f, 0.30f, 0.30f, 1.00f}; 113 114 SkScalar* positions[NUM_ROWS] = { 115 nullptr, 116 nullptr, 117 row3, 118 row4, 119 row5, 120 row6, 121 row7, 122 row8, 123 }; 124 125 int numGradientColors[NUM_ROWS] = { 126 2, 127 3, 128 3, 129 5, 130 4, 131 3, 132 3, 133 4, 134 }; 135 136 SkShader::TileMode tilemodes[NUM_COLS] = { 137 SkShader::kClamp_TileMode, 138 SkShader::kRepeat_TileMode, 139 SkShader::kMirror_TileMode, 140 }; 141 142 for (int cellRow = 0; cellRow < NUM_ROWS; cellRow++) { 143 for (int cellCol = 0; cellCol < NUM_COLS; cellCol++) { 144 create_gradient_points(cellRow, cellCol, points); 145 146 auto shader = SkGradientShader::MakeLinear( 147 points, 148 colors, 149 positions[cellRow], 150 numGradientColors[cellRow], 151 tilemodes[cellCol], 152 0, 153 nullptr); 154 155 shade_rect(canvas, shader, cellRow, cellCol); 156 } 157 } 158 } 159 160 private: 161 typedef skiagm::GM INHERITED; 162 }; 163 164 DEF_GM(return new HardstopGradientShaderGM;) 165