1/*
2 * Copyright 2011 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 "gm.h"
9#include "SkCanvas.h"
10#include "SkPath.h"
11#include "SkGradientShader.h"
12#include "SkTypeface.h"
13
14static SkShader* make_heatGradient(const SkPoint pts[2]) {
15    const SkColor bw[] = { SK_ColorBLACK, SK_ColorWHITE };
16
17    return SkGradientShader::CreateLinear(pts, bw, NULL,
18                                          SK_ARRAY_COUNT(bw),
19                                          SkShader::kClamp_TileMode);
20}
21
22static bool setFont(SkPaint* paint, const char name[]) {
23    SkTypeface* tf = sk_tool_utils::create_portable_typeface(name, SkTypeface::kNormal);
24    if (tf) {
25        paint->setTypeface(tf)->unref();
26        return true;
27    }
28    return false;
29}
30
31/**
32   Test a set of clipping problems discovered while writing blitAntiRect,
33   and test all the code paths through the clipping blitters.
34   Each region should show as a blue center surrounded by a 2px green
35   border, with no red.
36*/
37
38#define HEIGHT 480
39
40class GammaTextGM : public skiagm::GM {
41protected:
42    SkString onShortName() override {
43        return SkString("gammatext");
44    }
45
46    SkISize onISize() override {
47        return SkISize::Make(1024, HEIGHT);
48    }
49
50    static void drawGrad(SkCanvas* canvas) {
51        SkPoint pts[] = { { 0, 0 }, { 0, SkIntToScalar(HEIGHT) } };
52        SkShader* s = make_heatGradient(pts);
53
54        canvas->clear(SK_ColorRED);
55        SkPaint paint;
56        paint.setShader(s)->unref();
57        SkRect r = { 0, 0, SkIntToScalar(1024), SkIntToScalar(HEIGHT) };
58        canvas->drawRect(r, paint);
59    }
60
61    void onDraw(SkCanvas* canvas) override {
62        drawGrad(canvas);
63
64        const SkColor fg[] = {
65            0xFFFFFFFF,
66            0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
67            0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
68            0xFF000000,
69        };
70
71        const char* text = "Hamburgefons";
72        size_t len = strlen(text);
73
74        SkPaint paint;
75        setFont(&paint, "Times");
76        paint.setTextSize(SkIntToScalar(16));
77        paint.setAntiAlias(true);
78        paint.setLCDRenderText(true);
79
80        SkScalar x = SkIntToScalar(10);
81        for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
82            paint.setColor(fg[i]);
83
84            SkScalar y = SkIntToScalar(40);
85            SkScalar stopy = SkIntToScalar(HEIGHT);
86            while (y < stopy) {
87                canvas->drawText(text, len, x, y, paint);
88                y += paint.getTextSize() * 2;
89            }
90            x += SkIntToScalar(1024) / SK_ARRAY_COUNT(fg);
91        }
92    }
93
94private:
95    typedef skiagm::GM INHERITED;
96};
97
98DEF_GM( return new GammaTextGM; )
99
100//////////////////////////////////////////////////////////////////////////////
101
102static SkShader* make_gradient(SkColor c) {
103    const SkPoint pts[] = { { 0, 0 }, { 240, 0 } };
104    SkColor colors[2];
105    colors[0] = c;
106    colors[1] = SkColorSetA(c, 0);
107    return SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
108}
109
110static void set_face(SkPaint* paint) {
111    SkTypeface* face = SkTypeface::CreateFromName("serif", SkTypeface::kItalic);
112    SkSafeUnref(paint->setTypeface(face));
113}
114
115static void draw_pair(SkCanvas* canvas, SkPaint* paint, SkShader* shader) {
116    const char text[] = "Now is the time for all good";
117    const size_t len = strlen(text);
118
119    paint->setShader(NULL);
120    canvas->drawText(text, len, 10, 20, *paint);
121    paint->setShader(SkShader::CreateColorShader(paint->getColor()))->unref();
122    canvas->drawText(text, len, 10, 40, *paint);
123    paint->setShader(shader);
124    canvas->drawText(text, len, 10, 60, *paint);
125}
126
127class GammaShaderTextGM : public skiagm::GM {
128    SkShader* fShaders[3];
129    SkColor fColors[3];
130
131public:
132    GammaShaderTextGM() {
133        const SkColor colors[] = { SK_ColorBLACK, SK_ColorRED, SK_ColorBLUE };
134        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
135            fShaders[i] = NULL;
136            fColors[i] = colors[i];
137        }
138    }
139
140    ~GammaShaderTextGM() override {
141        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
142            SkSafeUnref(fShaders[i]);
143        }
144    }
145
146protected:
147    SkString onShortName() override {
148        return SkString("gammagradienttext");
149    }
150
151    SkISize onISize() override {
152        return SkISize::Make(300, 300);
153    }
154
155    void onOnceBeforeDraw() override {
156        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
157            fShaders[i] = make_gradient(fColors[i]);
158        }
159    }
160
161    void onDraw(SkCanvas* canvas) override {
162        SkPaint paint;
163        paint.setAntiAlias(true);
164        paint.setLCDRenderText(true);
165        paint.setTextSize(18);
166        set_face(&paint);
167
168        for (size_t i = 0; i < SK_ARRAY_COUNT(fShaders); ++i) {
169            paint.setColor(fColors[i]);
170            draw_pair(canvas, &paint, fShaders[i]);
171            canvas->translate(0, 80);
172        }
173    }
174
175private:
176    typedef skiagm::GM INHERITED;
177};
178
179DEF_GM( return new GammaShaderTextGM; )
180
181