Home | History | Annotate | Download | only in gm
      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 #include "sk_tool_utils.h"
     22 
     23 constexpr SkColor gColors[] = {
     24     SK_ColorRED, SK_ColorYELLOW
     25 };
     26 
     27 // These annoying defines are necessary, because the only other alternative
     28 // is to use SkIntToScalar(...) everywhere.
     29 constexpr SkScalar sZero = 0;
     30 constexpr SkScalar sHalf = SK_ScalarHalf;
     31 constexpr SkScalar sOne = SK_Scalar1;
     32 
     33 // These arrays define the gradient stop points
     34 // as x1, y1, x2, y2 per gradient to draw.
     35 constexpr SkPoint linearPts[][2] = {
     36     {{sZero, sZero}, {sOne,  sZero}},
     37     {{sZero, sZero}, {sZero, sOne}},
     38     {{sOne,  sZero}, {sZero, sZero}},
     39     {{sZero, sOne},  {sZero, sZero}},
     40 
     41     {{sZero, sZero}, {sOne,  sOne}},
     42     {{sOne,  sOne},  {sZero, sZero}},
     43     {{sOne,  sZero}, {sZero, sOne}},
     44     {{sZero, sOne},  {sOne,  sZero}}
     45 };
     46 
     47 constexpr SkPoint radialPts[][2] = {
     48     {{sZero, sHalf}, {sOne,  sHalf}},
     49     {{sHalf, sZero}, {sHalf, sOne}},
     50     {{sOne,  sHalf}, {sZero, sHalf}},
     51     {{sHalf, sOne},  {sHalf, sZero}},
     52 
     53     {{sZero, sZero}, {sOne,  sOne}},
     54     {{sOne,  sOne},  {sZero, sZero}},
     55     {{sOne,  sZero}, {sZero, sOne}},
     56     {{sZero, sOne},  {sOne,  sZero}}
     57 };
     58 
     59 // These define the pixels allocated to each gradient image.
     60 constexpr SkScalar TESTGRID_X = SkIntToScalar(200);
     61 constexpr SkScalar TESTGRID_Y = SkIntToScalar(200);
     62 
     63 constexpr int IMAGES_X = 4;             // number of images per row
     64 
     65 static sk_sp<SkShader> make_linear_gradient(const SkPoint pts[2], const SkMatrix& localMatrix) {
     66     return SkGradientShader::MakeLinear(pts, gColors, nullptr, SK_ARRAY_COUNT(gColors),
     67                                         SkShader::kClamp_TileMode, 0, &localMatrix);
     68 }
     69 
     70 static sk_sp<SkShader> make_radial_gradient(const SkPoint pts[2], const SkMatrix& localMatrix) {
     71     SkPoint center;
     72     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
     73                SkScalarAve(pts[0].fY, pts[1].fY));
     74     float radius = (center - pts[0]).length();
     75     return SkGradientShader::MakeRadial(center, radius, gColors, nullptr, SK_ARRAY_COUNT(gColors),
     76                                         SkShader::kClamp_TileMode, 0, &localMatrix);
     77 }
     78 
     79 static void draw_gradients(SkCanvas* canvas,
     80                            sk_sp<SkShader> (*makeShader)(const SkPoint[2], const SkMatrix&),
     81                            const SkPoint ptsArray[][2], int numImages) {
     82     // Use some nice prime numbers for the rectangle and matrix with
     83     // different scaling along the x and y axes (which is the bug this
     84     // test addresses, where incorrect order of operations mixed up the axes)
     85     SkRect rectGrad = {
     86         SkIntToScalar(43),  SkIntToScalar(61),
     87         SkIntToScalar(181), SkIntToScalar(167) };
     88     SkMatrix shaderMat;
     89     shaderMat.setScale(rectGrad.width(), rectGrad.height());
     90     shaderMat.postTranslate(rectGrad.left(), rectGrad.top());
     91 
     92     canvas->save();
     93     for (int i = 0; i < numImages; i++) {
     94         // Advance line downwards if necessary.
     95         if (i % IMAGES_X == 0 && i != 0) {
     96             canvas->restore();
     97             canvas->translate(0, TESTGRID_Y);
     98             canvas->save();
     99         }
    100 
    101         SkPaint paint;
    102         paint.setShader(makeShader(*ptsArray, shaderMat));
    103         canvas->drawRect(rectGrad, paint);
    104 
    105         // Advance to next position.
    106         canvas->translate(TESTGRID_X, 0);
    107         ptsArray++;
    108     }
    109     canvas->restore();
    110 }
    111 
    112 DEF_SIMPLE_GM_BG(gradient_matrix, canvas, 800, 800,
    113                  sk_tool_utils::color_to_565(0xFFDDDDDD)) {
    114         draw_gradients(canvas, &make_linear_gradient,
    115                       linearPts, SK_ARRAY_COUNT(linearPts));
    116 
    117         canvas->translate(0, TESTGRID_Y);
    118 
    119         draw_gradients(canvas, &make_radial_gradient,
    120                       radialPts, SK_ARRAY_COUNT(radialPts));
    121 }
    122