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
8#include "gm.h"
9#include "sk_tool_utils.h"
10#include "SkCanvas.h"
11#include "SkGradientShader.h"
12#include "SkPath.h"
13#include "SkSurface.h"
14
15#define W   SkIntToScalar(80)
16#define H   SkIntToScalar(60)
17
18typedef void (*PaintProc)(SkPaint*);
19
20static void identity_paintproc(SkPaint* paint) {
21    paint->setShader(nullptr);
22}
23
24static void gradient_paintproc(SkPaint* paint) {
25    const SkColor colors[] = { SK_ColorGREEN, SK_ColorBLUE };
26    const SkPoint pts[] = { { 0, 0 }, { W, H } };
27    paint->setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
28                                                  SkShader::kClamp_TileMode));
29}
30
31typedef void (*Proc)(SkCanvas*, const SkPaint&);
32
33static void draw_hair(SkCanvas* canvas, const SkPaint& paint) {
34    SkPaint p(paint);
35    p.setStrokeWidth(0);
36    canvas->drawLine(0, 0, W, H, p);
37}
38
39static void draw_thick(SkCanvas* canvas, const SkPaint& paint) {
40    SkPaint p(paint);
41    p.setStrokeWidth(H/5);
42    canvas->drawLine(0, 0, W, H, p);
43}
44
45static void draw_rect(SkCanvas* canvas, const SkPaint& paint) {
46    canvas->drawRect(SkRect::MakeWH(W, H), paint);
47}
48
49static void draw_oval(SkCanvas* canvas, const SkPaint& paint) {
50    canvas->drawOval(SkRect::MakeWH(W, H), paint);
51}
52
53static void draw_text(SkCanvas* canvas, const SkPaint& paint) {
54    SkPaint p(paint);
55    p.setTextSize(H/4);
56    canvas->drawString("Hamburge", 0, H*2/3, p);
57}
58
59class SrcModeGM : public skiagm::GM {
60    SkPath fPath;
61public:
62    SrcModeGM() {
63        this->setBGColor(SK_ColorBLACK);
64    }
65
66protected:
67    virtual SkString onShortName() {
68        return SkString("srcmode");
69    }
70
71    virtual SkISize onISize() {
72        return SkISize::Make(640, 760);
73    }
74
75    void drawContent(SkCanvas* canvas) {
76        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
77
78        SkPaint paint;
79        sk_tool_utils::set_portable_typeface(&paint);
80        paint.setColor(0x80F60000);
81
82        const Proc procs[] = {
83            draw_hair, draw_thick, draw_rect, draw_oval, draw_text
84        };
85
86        const SkBlendMode modes[] = {
87            SkBlendMode::kSrcOver, SkBlendMode::kSrc, SkBlendMode::kClear
88        };
89
90        const PaintProc paintProcs[] = {
91            identity_paintproc, gradient_paintproc
92        };
93
94        for (int aa = 0; aa <= 1; ++aa) {
95            paint.setAntiAlias(SkToBool(aa));
96            canvas->save();
97            for (size_t i = 0; i < SK_ARRAY_COUNT(paintProcs); ++i) {
98                paintProcs[i](&paint);
99                for (size_t x = 0; x < SK_ARRAY_COUNT(modes); ++x) {
100                    paint.setBlendMode(modes[x]);
101                    canvas->save();
102                    for (size_t y = 0; y < SK_ARRAY_COUNT(procs); ++y) {
103                        procs[y](canvas, paint);
104                        canvas->translate(0, H * 5 / 4);
105                    }
106                    canvas->restore();
107                    canvas->translate(W * 5 / 4, 0);
108                }
109            }
110            canvas->restore();
111            canvas->translate(0, (H * 5 / 4) * SK_ARRAY_COUNT(procs));
112        }
113    }
114
115    static sk_sp<SkSurface> compat_surface(SkCanvas* canvas, const SkISize& size, bool skipGPU) {
116        SkImageInfo info = SkImageInfo::MakeN32Premul(size);
117
118        bool callNewSurface = true;
119#if SK_SUPPORT_GPU
120        if (canvas->getGrContext() && skipGPU) {
121            callNewSurface = false;
122        }
123#endif
124        sk_sp<SkSurface> surface = callNewSurface ? canvas->makeSurface(info) : nullptr;
125        if (nullptr == surface) {
126            // picture canvas will return null, so fall-back to raster
127            surface = SkSurface::MakeRaster(info);
128        }
129        return surface;
130    }
131
132    virtual void onDraw(SkCanvas* canvas) {
133        auto surf(compat_surface(canvas, this->getISize(), this->isCanvasDeferred()));
134        surf->getCanvas()->drawColor(SK_ColorWHITE);
135        this->drawContent(surf->getCanvas());
136        surf->draw(canvas, 0, 0, nullptr);
137    }
138
139private:
140    typedef skiagm::GM INHERITED;
141};
142
143///////////////////////////////////////////////////////////////////////////////
144
145DEF_GM(return new SrcModeGM;)
146