gradient_matrix.cpp revision 910f694aefb0b671dd8522a9afe9b6be645701c1
1/* 2 * Copyright 2013 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#include "SkCanvas.h" 9#include "SkColor.h" 10#include "SkGradientShader.h" 11#include "SkMatrix.h" 12#include "SkPaint.h" 13#include "SkPoint.h" 14#include "SkRect.h" 15#include "SkRefCnt.h" 16#include "SkScalar.h" 17#include "SkSize.h" 18#include "SkString.h" 19 20#include "gm.h" 21 22static const SkColor gColors[] = { 23 SK_ColorRED, SK_ColorYELLOW 24}; 25 26// These annoying defines are necessary, because the only other alternative 27// is to use SkIntToScalar(...) everywhere. 28static const SkScalar sZero = 0; 29static const SkScalar sHalf = SK_ScalarHalf; 30static const SkScalar sOne = SK_Scalar1; 31 32// These arrays define the gradient stop points 33// as x1, y1, x2, y2 per gradient to draw. 34static const SkPoint linearPts[][2] = { 35 {{sZero, sZero}, {sOne, sZero}}, 36 {{sZero, sZero}, {sZero, sOne}}, 37 {{sOne, sZero}, {sZero, sZero}}, 38 {{sZero, sOne}, {sZero, sZero}}, 39 40 {{sZero, sZero}, {sOne, sOne}}, 41 {{sOne, sOne}, {sZero, sZero}}, 42 {{sOne, sZero}, {sZero, sOne}}, 43 {{sZero, sOne}, {sOne, sZero}} 44}; 45 46static const SkPoint radialPts[][2] = { 47 {{sZero, sHalf}, {sOne, sHalf}}, 48 {{sHalf, sZero}, {sHalf, sOne}}, 49 {{sOne, sHalf}, {sZero, sHalf}}, 50 {{sHalf, sOne}, {sHalf, sZero}}, 51 52 {{sZero, sZero}, {sOne, sOne}}, 53 {{sOne, sOne}, {sZero, sZero}}, 54 {{sOne, sZero}, {sZero, sOne}}, 55 {{sZero, sOne}, {sOne, sZero}} 56}; 57 58// These define the pixels allocated to each gradient image. 59static const SkScalar TESTGRID_X = SkIntToScalar(200); 60static const SkScalar TESTGRID_Y = SkIntToScalar(200); 61 62static const int IMAGES_X = 4; // number of images per row 63 64static SkShader* make_linear_gradient(const SkPoint pts[2]) { 65 return SkGradientShader::CreateLinear(pts, gColors, NULL, SK_ARRAY_COUNT(gColors), 66 SkShader::kClamp_TileMode, NULL); 67} 68 69static SkShader* make_radial_gradient(const SkPoint pts[2]) { 70 SkPoint center; 71 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 72 SkScalarAve(pts[0].fY, pts[1].fY)); 73 float radius = (center - pts[0]).length(); 74 return SkGradientShader::CreateRadial(center, radius, gColors, NULL, SK_ARRAY_COUNT(gColors), 75 SkShader::kClamp_TileMode, NULL); 76} 77 78static void draw_gradients(SkCanvas* canvas, SkShader* (*makeShader)(const SkPoint[2]), 79 const SkPoint ptsArray[][2], int numImages) { 80 // Use some nice prime numbers for the rectangle and matrix with 81 // different scaling along the x and y axes (which is the bug this 82 // test addresses, where incorrect order of operations mixed up the axes) 83 SkRect rectGrad = { 84 SkIntToScalar(43), SkIntToScalar(61), 85 SkIntToScalar(181), SkIntToScalar(167) }; 86 SkMatrix shaderMat; 87 shaderMat.setScale(rectGrad.width(), rectGrad.height()); 88 shaderMat.postTranslate(rectGrad.left(), rectGrad.top()); 89 90 canvas->save(); 91 for (int i = 0; i < numImages; i++) { 92 // Advance line downwards if necessary. 93 if (i % IMAGES_X == 0 && i != 0) { 94 canvas->restore(); 95 canvas->translate(0, TESTGRID_Y); 96 canvas->save(); 97 } 98 99 // Setup shader and draw. 100 SkAutoTUnref<SkShader> shader(makeShader(*ptsArray)); 101 shader->setLocalMatrix(shaderMat); 102 103 SkPaint paint; 104 paint.setShader(shader); 105 canvas->drawRect(rectGrad, paint); 106 107 // Advance to next position. 108 canvas->translate(TESTGRID_X, 0); 109 ptsArray++; 110 } 111 canvas->restore(); 112} 113 114namespace skiagm { 115 116class GradientMatrixGM : public GM { 117public: 118 GradientMatrixGM() { 119 this->setBGColor(0xFFDDDDDD); 120 } 121 122protected: 123 SkString onShortName() SK_OVERRIDE { 124 return SkString("gradient_matrix"); 125 } 126 127 virtual SkISize onISize() SK_OVERRIDE { 128 return SkISize::Make(800, 800); 129 } 130 131 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 132 draw_gradients(canvas, &make_linear_gradient, 133 linearPts, SK_ARRAY_COUNT(linearPts)); 134 135 canvas->translate(0, TESTGRID_Y); 136 137 draw_gradients(canvas, &make_radial_gradient, 138 radialPts, SK_ARRAY_COUNT(radialPts)); 139 } 140 141private: 142 typedef GM INHERITED; 143}; 144 145DEF_GM( return new GradientMatrixGM; ) 146} 147