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>
36 SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef fontRef);
37 #endif
38
setNamedTypeface(SkPaint * paint,const char name[])39 static void setNamedTypeface(SkPaint* paint, const char name[]) {
40 SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
41 paint->setTypeface(face);
42 SkSafeUnref(face);
43 }
44
45 static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
46
47 class XfermodesBlurView : public SampleView {
48 SkBitmap fBG;
49 SkBitmap fSrcB, fDstB;
50
draw_mode(SkCanvas * canvas,SkXfermode * mode,int alpha,SkScalar x,SkScalar y)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
98 public:
99 const static int W = 64;
100 const static int H = 64;
XfermodesBlurView()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
110 protected:
111 // overrides from SkEventSink
onQuery(SkEvent * evt)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
onDrawContent(SkCanvas * canvas)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
231 private:
232 typedef SampleView INHERITED;
233 };
234
235 //////////////////////////////////////////////////////////////////////////////
236
MyFactory()237 static SkView* MyFactory() { return new XfermodesBlurView; }
238 static SkViewRegister reg(MyFactory);
239