1/*
2 * Copyright 2012 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#include "gm.h"
8#include "SkGradientShader.h"
9
10namespace skiagm {
11
12static SkShader* MakeLinear(SkScalar width, SkScalar height, bool alternate,
13                            const SkMatrix& localMatrix) {
14  SkPoint pts[2] = { {0, 0}, {width, height}};
15  SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN};
16  if (alternate) {
17    pts[1].fY = 0;
18    colors[0] = SK_ColorBLUE;
19    colors[1] = SK_ColorYELLOW;
20  }
21  return SkGradientShader::CreateLinear(pts, colors, NULL, 2,
22                                        SkShader::kClamp_TileMode, 0, &localMatrix);
23}
24
25///////////////////////////////////////////////////////////////////////////////
26
27class ShaderBoundsGM : public GM {
28public:
29    typedef SkShader* (*ShaderGenFunc)(SkScalar width, SkScalar height,
30                                       bool alternate, const SkMatrix& localMatrix);
31    ShaderBoundsGM(ShaderGenFunc maker, const SkString& name)
32        : fShaderMaker(maker),
33          fName(name) {
34    }
35
36protected:
37    virtual uint32_t onGetFlags() const SK_OVERRIDE {
38        return kSkipTiled_Flag;
39    }
40
41    SkString onShortName() {
42        return fName;
43    }
44
45    virtual SkISize onISize() { return SkISize::Make(320, 240); }
46
47    virtual SkMatrix onGetInitialTransform() const SK_OVERRIDE {
48        SkMatrix result;
49        SkScalar scale = 0.8f;
50        result.setScale(scale, scale);
51        result.postTranslate(SkIntToScalar(7), SkIntToScalar(23));
52        return result;
53    }
54
55    virtual void onDraw(SkCanvas* canvas) {
56        // The PDF device has already clipped to the content area, but we
57        // do it again here so that the raster and pdf results are consistent.
58        canvas->clipRect(SkRect::MakeWH(SkIntToScalar(320),
59                                        SkIntToScalar(240)));
60
61        SkMatrix canvasScale;
62        SkScalar scale = 0.7f;
63        canvasScale.setScale(scale, scale);
64        canvas->concat(canvasScale);
65
66        // Background shader.
67        SkPaint paint;
68        paint.setShader(MakeShader(559, 387, false))->unref();
69        SkRect r = SkRect::MakeXYWH(SkIntToScalar(-12), SkIntToScalar(-41),
70                                    SkIntToScalar(571), SkIntToScalar(428));
71        canvas->drawRect(r, paint);
72
73        // Constrained shader.
74        paint.setShader(MakeShader(101, 151, true))->unref();
75        r = SkRect::MakeXYWH(SkIntToScalar(43), SkIntToScalar(71),
76                             SkIntToScalar(101), SkIntToScalar(151));
77        canvas->clipRect(r);
78        canvas->drawRect(r, paint);
79    }
80
81    SkShader* MakeShader(int width, int height, bool background) {
82        SkScalar scale = 0.5f;
83        if (background) {
84            scale = 0.6f;
85        }
86        SkScalar shaderWidth = SkScalarDiv(SkIntToScalar(width), scale);
87        SkScalar shaderHeight = SkScalarDiv(SkIntToScalar(height), scale);
88        SkMatrix shaderScale;
89        shaderScale.setScale(scale, scale);
90        SkShader* shader = fShaderMaker(shaderWidth, shaderHeight, background, shaderScale);
91        return shader;
92    }
93
94private:
95    typedef GM INHERITED;
96
97    ShaderGenFunc fShaderMaker;
98    SkString fName;
99
100    SkShader* MakeShader(bool background);
101};
102
103///////////////////////////////////////////////////////////////////////////////
104
105static GM* MyFactory(void*) {
106    return new ShaderBoundsGM(MakeLinear, SkString("shaderbounds_linear"));
107}
108static GMRegistry reg(MyFactory);
109
110}
111