1ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel/*
2ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel * Copyright 2014 Google Inc.
3ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel *
4ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel * Use of this source code is governed by a BSD-style license that can be
5ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel * found in the LICENSE file.
6ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel */
7ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "gm.h"
8ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "SkBitmap.h"
9ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "SkGradientShader.h"
10ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "SkShader.h"
11ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "SkXfermode.h"
12ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#include "../src/fonts/SkGScalerContext.h"
13ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
14ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielnamespace skiagm {
15ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
16ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielstatic uint16_t gData[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
17ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
18ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielclass ColorTypeXfermodeGM : public GM {
19ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    SkBitmap    fBG;
20ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
2136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onOnceBeforeDraw() override {
22ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        fBG.installPixels(SkImageInfo::Make(2, 2, kARGB_4444_SkColorType,
23ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                            kOpaque_SkAlphaType), gData, 4);
24ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
25ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
26ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielpublic:
27ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    const static int W = 64;
28ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    const static int H = 64;
29ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    ColorTypeXfermodeGM() {
30ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        const SkColor colors[] = {
31ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
32ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SK_ColorMAGENTA, SK_ColorCYAN, SK_ColorYELLOW
33ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        };
34ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkMatrix local;
35ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        local.setRotate(180);
36ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkShader* s = SkGradientShader::CreateSweep(0,0, colors, NULL,
37ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                                    SK_ARRAY_COUNT(colors), 0, &local);
38ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
39ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkPaint paint;
40ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        paint.setAntiAlias(true);
41ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        paint.setShader(s)->unref();
42ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
43ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkTypeface* orig = sk_tool_utils::create_portable_typeface("Times",
44ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                                            SkTypeface::kBold);
45ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        if (NULL == orig) {
46ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            orig = SkTypeface::RefDefault();
47ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        }
48ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        fColorType = SkNEW_ARGS(SkGTypeface, (orig, paint));
49ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        orig->unref();
50ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
51ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
52ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    virtual ~ColorTypeXfermodeGM() {
53ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        fColorType->unref();
54ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
55ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
56ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielprotected:
5736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    virtual SkString onShortName() override {
58ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        return SkString("colortype_xfermodes");
59ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
60ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
6136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    virtual SkISize onISize() override {
62ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        return SkISize::Make(400, 640);
63ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
64ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
6536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    virtual void onDraw(SkCanvas* canvas) override {
66ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
67ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
68ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        const struct {
69ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SkXfermode::Mode  fMode;
70ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            const char*       fLabel;
71ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        } gModes[] = {
72ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kClear_Mode,        "Clear"       },
73ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSrc_Mode,          "Src"         },
74ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDst_Mode,          "Dst"         },
75ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSrcOver_Mode,      "SrcOver"     },
76ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDstOver_Mode,      "DstOver"     },
77ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSrcIn_Mode,        "SrcIn"       },
78ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDstIn_Mode,        "DstIn"       },
79ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSrcOut_Mode,       "SrcOut"      },
80ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDstOut_Mode,       "DstOut"      },
81ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSrcATop_Mode,      "SrcATop"     },
82ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDstATop_Mode,      "DstATop"     },
83ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
84ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kXor_Mode,          "Xor"         },
85ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kPlus_Mode,         "Plus"        },
86ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kModulate_Mode,     "Modulate"    },
87ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kScreen_Mode,       "Screen"      },
88ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kOverlay_Mode,      "Overlay"     },
89ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDarken_Mode,       "Darken"      },
90ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kLighten_Mode,      "Lighten"     },
91ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kColorDodge_Mode,   "ColorDodge"  },
92ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kColorBurn_Mode,    "ColorBurn"   },
93ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kHardLight_Mode,    "HardLight"   },
94ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSoftLight_Mode,    "SoftLight"   },
95ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kDifference_Mode,   "Difference"  },
96ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kExclusion_Mode,    "Exclusion"   },
97ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kMultiply_Mode,     "Multiply"    },
98ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kHue_Mode,          "Hue"         },
99ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kSaturation_Mode,   "Saturation"  },
100ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kColor_Mode,        "Color"       },
101ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            { SkXfermode::kLuminosity_Mode,   "Luminosity"  },
102ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        };
103ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
104ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        const SkScalar w = SkIntToScalar(W);
105ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        const SkScalar h = SkIntToScalar(H);
106ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkMatrix m;
107ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
108ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkShader* s = SkShader::CreateBitmapShader(fBG,
109ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                                   SkShader::kRepeat_TileMode,
110ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                                   SkShader::kRepeat_TileMode,
111ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                                                   &m);
112ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
113ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkPaint labelP;
114ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        labelP.setAntiAlias(true);
115ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        sk_tool_utils::set_portable_typeface(&labelP);
116ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        labelP.setTextAlign(SkPaint::kCenter_Align);
117ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
118ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkPaint textP;
119ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        textP.setAntiAlias(true);
120ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        textP.setTypeface(fColorType);
121ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        textP.setTextSize(SkIntToScalar(70));
122ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
123ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        const int W = 5;
124ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
125ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkScalar x0 = 0;
126ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkScalar y0 = 0;
127ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        SkScalar x = x0, y = y0;
128ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
129ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
130ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SkAutoUnref aur(mode);
131ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SkRect r;
132ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            r.set(x, y, x+w, y+h);
133ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
134ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            SkPaint p;
135ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            p.setStyle(SkPaint::kFill_Style);
136ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            p.setShader(s);
137ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            canvas->drawRect(r, p);
138ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
139ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
140ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            p.setStyle(SkPaint::kStroke_Style);
141ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            p.setShader(NULL);
142ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            canvas->drawRect(r, p);
143ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
144ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            textP.setXfermode(mode);
145ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            canvas->drawText("H", 1, x+ w/10.f, y + 7.f*h/8.f, textP);
146ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#if 1
147ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
148ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                             x + w/2, y - labelP.getTextSize()/2, labelP);
149ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel#endif
150ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            x += w + SkIntToScalar(10);
151ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            if ((i % W) == W - 1) {
152ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                x = x0;
153ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel                y += h + SkIntToScalar(30);
154ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel            }
155ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        }
156ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel        s->unref();
157ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    }
158ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
159ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielprivate:
160ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    SkTypeface* fColorType;
161ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
162ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel    typedef GM INHERITED;
163ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel};
164ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
165ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel//////////////////////////////////////////////////////////////////////////////
166ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
167ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielstatic GM* MyFactory(void*) { return new ColorTypeXfermodeGM; }
168ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdanielstatic GMRegistry reg(MyFactory);
169ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel
170ed3af6648ffe1044d6fb3f6deac53711cb1280c8egdaniel}
171