SampleXfermodesBlur.cpp revision 045e62d715f5ee9b03deb5af3c750f8318096179
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SampleCode.h"
9#include "SkView.h"
10#include "SkCanvas.h"
11#include "Sk64.h"
12#include "SkCornerPathEffect.h"
13#include "SkGradientShader.h"
14#include "SkGraphics.h"
15#include "SkImageDecoder.h"
16#include "SkKernel33MaskFilter.h"
17#include "SkPath.h"
18#include "SkRandom.h"
19#include "SkRegion.h"
20#include "SkShader.h"
21#include "SkUtils.h"
22#include "SkColorPriv.h"
23#include "SkColorFilter.h"
24#include "SkTime.h"
25#include "SkTypeface.h"
26#include "SkXfermode.h"
27
28#include "SkStream.h"
29#include "SkXMLParser.h"
30#include "SkColorPriv.h"
31#include "SkImageDecoder.h"
32#include "SkBlurMaskFilter.h"
33
34#ifdef SK_BUILD_FOR_MAC
35#import <ApplicationServices/ApplicationServices.h>
36SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef);
37#endif
38
39static void setNamedTypeface(SkPaint* paint, const char name[]) {
40    SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
41    paint->setTypeface(face);
42    SkSafeUnref(face);
43}
44
45static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
46
47class XfermodesBlurView : public SampleView {
48    SkBitmap    fBG;
49    SkBitmap    fSrcB, fDstB;
50
51    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
52                   SkScalar x, SkScalar y) {
53        SkPaint p;
54        SkMaskFilter* mf = SkBlurMaskFilter::Create(5, SkBlurMaskFilter::kNormal_BlurStyle, 0);
55        p.setMaskFilter(mf)->unref();
56
57        SkScalar ww = SkIntToScalar(W);
58        SkScalar hh = SkIntToScalar(H);
59
60        // draw a circle covering the upper
61        // left three quarters of the canvas
62        p.setColor(0xFFCC44FF);
63        SkRect r;
64        r.set(0, 0, ww*3/4, hh*3/4);
65        r.offset(x, y);
66        canvas->drawOval(r, p);
67
68        p.setXfermode(mode);
69
70        // draw a square overlapping the circle
71        // in the lower right of the canvas
72        p.setColor(0x00AA6633 | alpha << 24);
73        r.set(ww/3, hh/3, ww*19/20, hh*19/20);
74        r.offset(x, y);
75        canvas->drawRect(r, p);
76
77#ifdef SK_BUILD_FOR_MAC
78        static const char* gNames[] = { "Arial", "Times", "Courier", "Lucida" };
79        for (int j = 0; j < SK_ARRAY_COUNT(gNames); ++j) {
80            CFStringRef name = CFStringCreateWithCString(NULL, gNames[j], kCFStringEncodingUTF8);
81            CTFontRef font = CTFontCreateWithName(name, 0, NULL);
82            SkTypeface* face = SkCreateTypefaceFromCTFont(font);
83            SkDebugf("%s ct:%p face:%p ats:%p\n", gNames[j], font, face, CTFontGetPlatformFont(font, NULL));
84            for (int i = 9; i <= 24; ++i) {
85                CTFontRef newFont = CTFontCreateCopyWithAttributes(font, i, NULL, NULL);
86                SkTypeface* newFace = SkCreateTypefaceFromCTFont(newFont);
87                SkDebugf("size:%d ct:%p face:%p ats:%p\n", i, newFont, newFace, CTFontGetPlatformFont(newFont, NULL));
88                newFace->unref();
89                CFRelease(newFont);
90            }
91            face->unref();
92            CFRelease(font);
93            CFRelease(name);
94        }
95#endif
96    }
97
98public:
99    const static int W = 64;
100    const static int H = 64;
101    XfermodesBlurView() {
102        const int W = 64;
103        const int H = 64;
104
105        fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
106        fBG.setPixels(gBG);
107        fBG.setIsOpaque(true);
108    }
109
110protected:
111    // overrides from SkEventSink
112    virtual bool onQuery(SkEvent* evt) {
113        if (SampleCode::TitleQ(*evt)) {
114            SampleCode::TitleR(evt, "XfermodesBlur");
115            return true;
116        }
117        return this->INHERITED::onQuery(evt);
118    }
119
120    virtual void onDrawContent(SkCanvas* canvas) {
121        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
122
123        if (false) {
124            SkPaint paint;
125            paint.setAntiAlias(true);
126            paint.setTextSize(50);
127            paint.setTypeface(SkTypeface::CreateFromName("Arial Unicode MS", SkTypeface::kNormal));
128            SkSafeUnref(paint.getTypeface());
129            char buffer[10];
130            size_t len = SkUTF8_FromUnichar(0x8500, buffer);
131            canvas->drawText(buffer, len, 40, 40, paint);
132            return;
133        }
134        if (false) {
135            SkPaint paint;
136            paint.setAntiAlias(true);
137
138            SkRect r0 = { 0, 0, 10.5f, 20 };
139            SkRect r1 = { 10.5f, 10, 20, 30 };
140            paint.setColor(SK_ColorRED);
141            canvas->drawRect(r0, paint);
142            paint.setColor(SK_ColorBLUE);
143            canvas->drawRect(r1, paint);
144            return;
145        }
146
147        const struct {
148            SkXfermode::Mode  fMode;
149            const char*         fLabel;
150        } gModes[] = {
151            { SkXfermode::kClear_Mode,    "Clear"     },
152            { SkXfermode::kSrc_Mode,      "Src"       },
153            { SkXfermode::kDst_Mode,      "Dst"       },
154            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
155            { SkXfermode::kDstOver_Mode,  "DstOver"   },
156            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
157            { SkXfermode::kDstIn_Mode,    "DstIn"     },
158            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
159            { SkXfermode::kDstOut_Mode,   "DstOut"    },
160            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
161            { SkXfermode::kDstATop_Mode,  "DstATop"   },
162            { SkXfermode::kXor_Mode,      "Xor"       },
163
164            { SkXfermode::kPlus_Mode,         "Plus"          },
165            /*{ SkXfermode::kMultiply_Mode,     "Multiply"      },
166            { SkXfermode::kScreen_Mode,       "Screen"        },
167            { SkXfermode::kOverlay_Mode,      "Overlay"       },
168            { SkXfermode::kDarken_Mode,       "Darken"        },
169            { SkXfermode::kLighten_Mode,      "Lighten"       },
170            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
171            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
172            { SkXfermode::kHardLight_Mode,    "HardLight"     },
173            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
174            { SkXfermode::kDifference_Mode,   "Difference"    },
175            { SkXfermode::kExclusion_Mode,    "Exclusion"     },*/
176        };
177
178        const SkScalar w = SkIntToScalar(W);
179        const SkScalar h = SkIntToScalar(H);
180        SkShader* s = SkShader::CreateBitmapShader(fBG,
181                                                   SkShader::kRepeat_TileMode,
182                                                   SkShader::kRepeat_TileMode);
183        SkMatrix m;
184        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
185        s->setLocalMatrix(m);
186
187        SkPaint labelP;
188        labelP.setAntiAlias(true);
189        labelP.setLCDRenderText(true);
190        labelP.setTextAlign(SkPaint::kCenter_Align);
191        setNamedTypeface(&labelP, "Menlo Regular");
192
193        const int W = 5;
194
195        SkScalar x0 = 0;
196        for (int twice = 0; twice < 2; twice++) {
197            SkScalar x = x0, y = 0;
198            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
199                SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
200                SkAutoUnref aur(mode);
201                SkRect r;
202                r.set(x, y, x+w, y+h);
203
204                SkPaint p;
205                p.setStyle(SkPaint::kFill_Style);
206                p.setShader(s);
207                canvas->drawRect(r, p);
208
209                canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
210                draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
211                canvas->restore();
212
213                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
214                p.setStyle(SkPaint::kStroke_Style);
215                p.setShader(NULL);
216                canvas->drawRect(r, p);
217
218                canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
219                                 x + w/2, y - labelP.getTextSize()/2, labelP);
220                x += w + SkIntToScalar(10);
221                if ((i % W) == W - 1) {
222                    x = x0;
223                    y += h + SkIntToScalar(30);
224                }
225            }
226            x0 += SkIntToScalar(400);
227        }
228        s->unref();
229    }
230
231private:
232    typedef SampleView INHERITED;
233};
234
235//////////////////////////////////////////////////////////////////////////////
236
237static SkView* MyFactory() { return new XfermodesBlurView; }
238static SkViewRegister reg(MyFactory);
239