blob: b94960dbe451d6755a2d57faa43ffe28dcd0d1d6 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SkCanvas.h"
2#include "SkDevice.h"
reed@google.comac10a2d2010-12-22 21:39:39 +00003#include "SkGpuCanvas.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00004#include "SkGraphics.h"
reed@android.comb08eb2b2009-01-06 20:16:26 +00005#include "SkImageEncoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00006#include "SkPaint.h"
7#include "SkPicture.h"
8#include "SkStream.h"
reed@android.com44177402009-11-23 21:07:51 +00009#include "SkTime.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkWindow.h"
11
12#include "SampleCode.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000013#include "GrContext.h"
reed@android.comf2b98d62010-12-20 18:26:13 +000014
15//#define DEFAULT_TO_GPU
16
reed@android.come191b162009-12-18 21:33:39 +000017extern SkView* create_overview(int, const SkViewFactory[]);
reed@android.com34245c72009-11-03 04:00:48 +000018
reed@android.comcb342352010-07-22 18:27:53 +000019#define SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +000020
21#define ANIMATING_EVENTTYPE "nextSample"
22#define ANIMATING_DELAY 750
23
reed@google.comac10a2d2010-12-22 21:39:39 +000024#ifdef SK_SUPPORT_GL
25 #include "GrGLConfig.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000026#endif
27
reed@android.com8a1c16f2008-12-17 15:59:43 +000028SkViewRegister* SkViewRegister::gHead;
29SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
30 static bool gOnce;
31 if (!gOnce) {
32 gHead = NULL;
33 gOnce = true;
34 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +000035
reed@android.com8a1c16f2008-12-17 15:59:43 +000036 fChain = gHead;
37 gHead = this;
38}
39
reed@android.comf2b98d62010-12-20 18:26:13 +000040#if defined(SK_SUPPORT_GL)
41 #define SK_USE_SHADERS
42#endif
43
twiz@google.com06c3b6b2011-03-14 16:58:39 +000044#ifdef SK_BUILD_FOR_MAC
reed@google.comf0b5f682011-03-11 20:08:25 +000045#include <CoreFoundation/CoreFoundation.h>
46#include <CoreFoundation/CFURLAccess.h>
47
48static void testpdf() {
49 CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
50 kCFStringEncodingUTF8);
51 CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
52 kCFURLPOSIXPathStyle,
53 false);
54 CFRelease(path);
55 CGRect box = CGRectMake(0, 0, 8*72, 10*72);
56 CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
57 CFRelease(url);
58
59 CGContextBeginPage(cg, &box);
60 CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
61 CGContextFillEllipseInRect(cg, r);
62 CGContextEndPage(cg);
63 CGContextRelease(cg);
64
65 if (false) {
66 SkBitmap bm;
67 bm.setConfig(SkBitmap::kA8_Config, 64, 64);
68 bm.allocPixels();
69 bm.eraseColor(0);
70
71 SkCanvas canvas(bm);
72
73 }
74}
75#endif
76
77//////////////////////////////////////////////////////////////////////////////
78
79#include "SkDrawFilter.h"
80
81class LCDTextDrawFilter : public SkDrawFilter {
82public:
83 enum Mode {
84 kNeutral_Mode,
85 kForceOn_Mode,
86 kForceOff_Mode
87 };
88
89 LCDTextDrawFilter(Mode mode) : fMode(mode) {}
90
91 virtual bool filter(SkCanvas*, SkPaint* paint, Type t) {
92 if (kText_Type == t && kNeutral_Mode != fMode) {
93 fPrevLCD = paint->isLCDRenderText();
94 paint->setLCDRenderText(kForceOn_Mode == fMode);
95 }
96 return true;
97 }
98
99 /** If filter() returned true, then restore() will be called to restore the
100 canvas/paint to their previous states
101 */
102 virtual void restore(SkCanvas*, SkPaint* paint, Type t) {
103 if (kText_Type == t && kNeutral_Mode != fMode) {
104 paint->setLCDRenderText(fPrevLCD);
105 }
106 }
107
108private:
109 Mode fMode;
110 bool fPrevLCD;
111};
112
113LCDTextDrawFilter::Mode cycle_lcdmode(LCDTextDrawFilter::Mode mode) {
114 static const LCDTextDrawFilter::Mode gCycle[] = {
115 /* kNeutral_Mode -> */ LCDTextDrawFilter::kForceOn_Mode,
116 /* kForceOn_Mode -> */ LCDTextDrawFilter::kForceOff_Mode,
117 /* kForceOff_Mode -> */ LCDTextDrawFilter::kNeutral_Mode
118 };
119 return gCycle[mode];
120}
121
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122//////////////////////////////////////////////////////////////////////////////
123
reed@android.comf2b98d62010-12-20 18:26:13 +0000124static const char gCharEvtName[] = "SampleCode_Char_Event";
125static const char gKeyEvtName[] = "SampleCode_Key_Event";
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126static const char gTitleEvtName[] = "SampleCode_Title_Event";
127static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
reed@android.comf2b98d62010-12-20 18:26:13 +0000128static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
129
130bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
131 if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
132 if (outUni) {
133 *outUni = evt.getFast32();
134 }
135 return true;
136 }
137 return false;
138}
139
140bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
141 if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
142 if (outKey) {
143 *outKey = (SkKey)evt.getFast32();
144 }
145 return true;
146 }
147 return false;
148}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000149
150bool SampleCode::TitleQ(const SkEvent& evt) {
151 return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
152}
153
154void SampleCode::TitleR(SkEvent* evt, const char title[]) {
155 SkASSERT(evt && TitleQ(*evt));
156 evt->setString(gTitleEvtName, title);
157}
158
159bool SampleCode::PrefSizeQ(const SkEvent& evt) {
160 return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
161}
162
163void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
164 SkASSERT(evt && PrefSizeQ(*evt));
165 SkScalar size[2];
166 size[0] = width;
167 size[1] = height;
168 evt->setScalars(gPrefSizeEvtName, 2, size);
169}
170
reed@android.comf2b98d62010-12-20 18:26:13 +0000171bool SampleCode::FastTextQ(const SkEvent& evt) {
172 return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
173}
174
175///////////////////////////////////////////////////////////////////////////////
176
reed@android.com44177402009-11-23 21:07:51 +0000177static SkMSec gAnimTime;
reed@android.comf2b98d62010-12-20 18:26:13 +0000178static SkMSec gAnimTimePrev;
179
reed@android.com44177402009-11-23 21:07:51 +0000180SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
reed@android.comf2b98d62010-12-20 18:26:13 +0000181SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
182SkScalar SampleCode::GetAnimSecondsDelta() {
183 return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
184}
reed@android.com44177402009-11-23 21:07:51 +0000185
186SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000187 // since gAnimTime can be up to 32 bits, we can't convert it to a float
188 // or we'll lose the low bits. Hence we use doubles for the intermediate
189 // calculations
190 double seconds = (double)gAnimTime / 1000.0;
191 double value = SkScalarToDouble(speed) * seconds;
reed@android.com44177402009-11-23 21:07:51 +0000192 if (period) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000193 value = ::fmod(value, SkScalarToDouble(period));
reed@android.com44177402009-11-23 21:07:51 +0000194 }
reed@android.comf2b98d62010-12-20 18:26:13 +0000195 return SkDoubleToScalar(value);
reed@android.com44177402009-11-23 21:07:51 +0000196}
197
reed@android.com8a1c16f2008-12-17 15:59:43 +0000198//////////////////////////////////////////////////////////////////////////////
199
reed@android.comf2b98d62010-12-20 18:26:13 +0000200static SkView* curr_view(SkWindow* wind) {
201 SkView::F2BIter iter(wind);
202 return iter.next();
203}
204
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205class SampleWindow : public SkOSWindow {
reed@android.com34245c72009-11-03 04:00:48 +0000206 SkTDArray<SkViewFactory> fSamples;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000207public:
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000208 SampleWindow(void* hwnd);
209 virtual ~SampleWindow();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000210
reed@android.come522ca52009-11-23 20:10:41 +0000211 virtual void draw(SkCanvas* canvas);
212
reed@android.com8a1c16f2008-12-17 15:59:43 +0000213protected:
214 virtual void onDraw(SkCanvas* canvas);
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000215 virtual bool onHandleKey(SkKey key);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000216 virtual bool onHandleChar(SkUnichar);
217 virtual void onSizeChange();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000218
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219 virtual SkCanvas* beforeChildren(SkCanvas*);
220 virtual void afterChildren(SkCanvas*);
reed@android.com6c5f6f22009-08-14 16:08:38 +0000221 virtual void beforeChild(SkView* child, SkCanvas* canvas);
222 virtual void afterChild(SkView* child, SkCanvas* canvas);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000223
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000224 virtual bool onEvent(const SkEvent& evt);
reed@android.comf2b98d62010-12-20 18:26:13 +0000225 virtual bool onQuery(SkEvent* evt);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000226
227#if 0
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000228 virtual bool handleChar(SkUnichar uni);
229 virtual bool handleEvent(const SkEvent& evt);
230 virtual bool handleKey(SkKey key);
231 virtual bool handleKeyUp(SkKey key);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000232
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000233 virtual bool onClick(Click* click);
234 virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 virtual bool onHandleKeyUp(SkKey key);
236#endif
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000237
reed@android.com8a1c16f2008-12-17 15:59:43 +0000238private:
reed@android.com34245c72009-11-03 04:00:48 +0000239 int fCurrIndex;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000240
reed@android.com8a1c16f2008-12-17 15:59:43 +0000241 SkPicture* fPicture;
reed@android.comf2b98d62010-12-20 18:26:13 +0000242 SkGpuCanvas* fGpuCanvas;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000243 GrContext* fGrContext;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000244 SkPath fClipPath;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000245
reed@android.com8a1c16f2008-12-17 15:59:43 +0000246 enum CanvasType {
247 kRaster_CanvasType,
248 kPicture_CanvasType,
reed@android.comf2b98d62010-12-20 18:26:13 +0000249 kGPU_CanvasType
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250 };
251 CanvasType fCanvasType;
252
253 bool fUseClip;
reed@android.come522ca52009-11-23 20:10:41 +0000254 bool fNClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000255 bool fRepeatDrawing;
256 bool fAnimating;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000257 bool fRotate;
258 bool fScale;
reed@android.comf2b98d62010-12-20 18:26:13 +0000259 bool fRequestGrabImage;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000260
reed@google.comf0b5f682011-03-11 20:08:25 +0000261 LCDTextDrawFilter::Mode fLCDMode;
262
reed@android.com8a1c16f2008-12-17 15:59:43 +0000263 int fScrollTestX, fScrollTestY;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000264
265 bool make3DReady();
266
reed@android.com8a1c16f2008-12-17 15:59:43 +0000267 void loadView(SkView*);
268 void updateTitle();
269 bool nextSample();
270
271 void postAnimatingEvent() {
272 if (fAnimating) {
273 SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
274 evt->post(this->getSinkID(), ANIMATING_DELAY);
275 }
276 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000277
278
reed@android.com8a1c16f2008-12-17 15:59:43 +0000279 static CanvasType cycle_canvastype(CanvasType);
280
281 typedef SkOSWindow INHERITED;
282};
283
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000284bool SampleWindow::make3DReady() {
285
286#if defined(SK_SUPPORT_GL)
bsalomon@google.com498a6232011-03-10 18:24:15 +0000287 if (attachGL()) {
288 if (NULL == fGrContext) {
289 #if defined(SK_USE_SHADERS)
290 fGrContext = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
291 #else
292 fGrContext = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
293 #endif
294 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000295
bsalomon@google.com498a6232011-03-10 18:24:15 +0000296 if (NULL != fGrContext) {
297 return true;
298 } else {
299 detachGL();
300 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000301 }
302#endif
303 SkDebugf("Failed to setup 3D");
304 return false;
305}
306
reed@android.com8a1c16f2008-12-17 15:59:43 +0000307SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
308 static const CanvasType gCT[] = {
309 kPicture_CanvasType,
reed@android.comf2b98d62010-12-20 18:26:13 +0000310 kGPU_CanvasType,
reed@android.com8a1c16f2008-12-17 15:59:43 +0000311 kRaster_CanvasType
312 };
313 return gCT[ct];
314}
315
316SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000317 fPicture = NULL;
reed@android.comf2b98d62010-12-20 18:26:13 +0000318 fGpuCanvas = NULL;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000319
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000320 fGrContext = NULL;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000321
reed@android.comf2b98d62010-12-20 18:26:13 +0000322#ifdef DEFAULT_TO_GPU
323 fCanvasType = kGPU_CanvasType;
324#else
reed@android.com8a1c16f2008-12-17 15:59:43 +0000325 fCanvasType = kRaster_CanvasType;
reed@android.comf2b98d62010-12-20 18:26:13 +0000326#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000327 fUseClip = false;
reed@android.come522ca52009-11-23 20:10:41 +0000328 fNClip = false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000329 fRepeatDrawing = false;
330 fAnimating = false;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000331 fRotate = false;
332 fScale = false;
reed@android.comf2b98d62010-12-20 18:26:13 +0000333 fRequestGrabImage = false;
reed@google.comf0b5f682011-03-11 20:08:25 +0000334 fLCDMode = LCDTextDrawFilter::kNeutral_Mode;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000335 fScrollTestX = fScrollTestY = 0;
336
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000337// this->setConfig(SkBitmap::kRGB_565_Config);
338 this->setConfig(SkBitmap::kARGB_8888_Config);
339 this->setVisibleP(true);
reed@android.comf2b98d62010-12-20 18:26:13 +0000340 this->setClipToBounds(false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000341
reed@android.com34245c72009-11-03 04:00:48 +0000342 {
343 const SkViewRegister* reg = SkViewRegister::Head();
344 while (reg) {
345 *fSamples.append() = reg->factory();
346 reg = reg->next();
347 }
348 }
349 fCurrIndex = 0;
reed@android.come0f13ee2009-11-04 19:40:25 +0000350 this->loadView(fSamples[fCurrIndex]());
reed@google.comf0b5f682011-03-11 20:08:25 +0000351
twiz@google.com06c3b6b2011-03-14 16:58:39 +0000352#ifdef SK_BUILD_FOR_MAC
reed@google.comf0b5f682011-03-11 20:08:25 +0000353 testpdf();
twiz@google.com06c3b6b2011-03-14 16:58:39 +0000354#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000355}
356
357SampleWindow::~SampleWindow() {
358 delete fPicture;
reed@android.comf2b98d62010-12-20 18:26:13 +0000359 delete fGpuCanvas;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000360 if (NULL != fGrContext) {
361 fGrContext->unref();
362 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000363}
364
reed@android.com55e76b22009-11-23 21:46:47 +0000365static SkBitmap capture_bitmap(SkCanvas* canvas) {
366 SkBitmap bm;
367 const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
368 src.copyTo(&bm, src.config());
369 return bm;
370}
371
372static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
373 SkBitmap* diff) {
374 const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000375
reed@android.com55e76b22009-11-23 21:46:47 +0000376 SkAutoLockPixels alp0(src);
377 SkAutoLockPixels alp1(orig);
378 for (int y = 0; y < src.height(); y++) {
379 const void* srcP = src.getAddr(0, y);
380 const void* origP = orig.getAddr(0, y);
381 size_t bytes = src.width() * src.bytesPerPixel();
382 if (memcmp(srcP, origP, bytes)) {
383 SkDebugf("---------- difference on line %d\n", y);
384 return true;
385 }
386 }
387 return false;
388}
389
reed@android.com44177402009-11-23 21:07:51 +0000390#define XCLIP_N 8
391#define YCLIP_N 8
reed@android.come522ca52009-11-23 20:10:41 +0000392
393void SampleWindow::draw(SkCanvas* canvas) {
reed@android.com44177402009-11-23 21:07:51 +0000394 // update the animation time
reed@android.comf2b98d62010-12-20 18:26:13 +0000395 gAnimTimePrev = gAnimTime;
reed@android.com44177402009-11-23 21:07:51 +0000396 gAnimTime = SkTime::GetMSecs();
397
reed@android.come522ca52009-11-23 20:10:41 +0000398 if (fNClip) {
reed@android.com55e76b22009-11-23 21:46:47 +0000399 this->INHERITED::draw(canvas);
400 SkBitmap orig = capture_bitmap(canvas);
reed@android.come522ca52009-11-23 20:10:41 +0000401
402 const SkScalar w = this->width();
403 const SkScalar h = this->height();
404 const SkScalar cw = w / XCLIP_N;
405 const SkScalar ch = h / YCLIP_N;
406 for (int y = 0; y < YCLIP_N; y++) {
reed@android.com55e76b22009-11-23 21:46:47 +0000407 SkRect r;
408 r.fTop = y * ch;
409 r.fBottom = (y + 1) * ch;
410 if (y == YCLIP_N - 1) {
411 r.fBottom = h;
412 }
reed@android.come522ca52009-11-23 20:10:41 +0000413 for (int x = 0; x < XCLIP_N; x++) {
414 SkAutoCanvasRestore acr(canvas, true);
reed@android.com55e76b22009-11-23 21:46:47 +0000415 r.fLeft = x * cw;
416 r.fRight = (x + 1) * cw;
417 if (x == XCLIP_N - 1) {
418 r.fRight = w;
419 }
reed@android.come522ca52009-11-23 20:10:41 +0000420 canvas->clipRect(r);
421 this->INHERITED::draw(canvas);
422 }
423 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000424
reed@android.com55e76b22009-11-23 21:46:47 +0000425 SkBitmap diff;
426 if (bitmap_diff(canvas, orig, &diff)) {
427 }
reed@android.come522ca52009-11-23 20:10:41 +0000428 } else {
429 this->INHERITED::draw(canvas);
430 }
431}
432
reed@android.com8a1c16f2008-12-17 15:59:43 +0000433void SampleWindow::onDraw(SkCanvas* canvas) {
434 if (fRepeatDrawing) {
435 this->inval(NULL);
436 }
437}
438
439#include "SkColorPriv.h"
440
441static void reverseRedAndBlue(const SkBitmap& bm) {
442 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
443 uint8_t* p = (uint8_t*)bm.getPixels();
444 uint8_t* stop = p + bm.getSize();
445 while (p < stop) {
446 // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
447 unsigned scale = SkAlpha255To256(p[3]);
448 unsigned r = p[2];
449 unsigned b = p[0];
450 p[0] = SkAlphaMul(r, scale);
451 p[1] = SkAlphaMul(p[1], scale);
452 p[2] = SkAlphaMul(b, scale);
453 p += 4;
454 }
455}
456
457SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000458 SkIPoint viewport;
459 bool alreadyGPU = canvas->getViewport(&viewport);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000460
reed@android.comf2b98d62010-12-20 18:26:13 +0000461 if (kGPU_CanvasType != fCanvasType) {
reed@android.com6efdc472008-12-19 18:24:35 +0000462#ifdef SK_SUPPORT_GL
reed@android.comf2b98d62010-12-20 18:26:13 +0000463 detachGL();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000464#endif
reed@android.comf2b98d62010-12-20 18:26:13 +0000465 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000466
reed@android.com8a1c16f2008-12-17 15:59:43 +0000467 switch (fCanvasType) {
468 case kRaster_CanvasType:
469 canvas = this->INHERITED::beforeChildren(canvas);
470 break;
471 case kPicture_CanvasType:
472 fPicture = new SkPicture;
473 canvas = fPicture->beginRecording(9999, 9999);
474 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000475 case kGPU_CanvasType: {
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000476 if (!alreadyGPU && make3DReady()) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000477 SkDevice* device = canvas->getDevice();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000478 const SkBitmap& bitmap = device->accessBitmap(true);
479
bsalomon@google.com5782d712011-01-21 21:03:59 +0000480 GrRenderTarget* renderTarget;
481 renderTarget = fGrContext->createRenderTargetFrom3DApiState();
482 fGpuCanvas = new SkGpuCanvas(fGrContext, renderTarget);
483 renderTarget->unref();
484
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000485 device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
486 bitmap.width(), bitmap.height(),
487 false, false);
reed@google.comac10a2d2010-12-22 21:39:39 +0000488 fGpuCanvas->setDevice(device)->unref();
reed@android.comf2b98d62010-12-20 18:26:13 +0000489 canvas = fGpuCanvas;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000490
reed@android.comf2b98d62010-12-20 18:26:13 +0000491 } else {
492 canvas = this->INHERITED::beforeChildren(canvas);
493 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000495 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000496 }
497
498 if (fUseClip) {
499 canvas->drawColor(0xFFFF88FF);
500 canvas->clipPath(fClipPath);
501 }
502
503 return canvas;
504}
505
506static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
507 const SkRegion& rgn) {
508 SkCanvas canvas(bm);
509 SkRegion inval(rgn);
510
511 inval.translate(r.fLeft, r.fTop);
512 canvas.clipRegion(inval);
513 canvas.drawColor(0xFFFF8080);
514}
515
516void SampleWindow::afterChildren(SkCanvas* orig) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000517 if (fRequestGrabImage) {
518 fRequestGrabImage = false;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000519
reed@android.comf2b98d62010-12-20 18:26:13 +0000520 SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig;
521 SkDevice* device = canvas->getDevice();
522 SkBitmap bitmap;
reed@google.com5ba2d5b2011-03-10 19:40:34 +0000523 SkIRect bounds = {
524 0, 0,
525 SkScalarRound(this->width()),
526 SkScalarRound(this->height())
527 };
reed@android.comf2b98d62010-12-20 18:26:13 +0000528 if (device->readPixels(bounds, &bitmap)) {
529 static int gSampleGrabCounter;
530 SkString name;
531 name.printf("sample_grab_%d", gSampleGrabCounter++);
532 SkImageEncoder::EncodeFile(name.c_str(), bitmap,
533 SkImageEncoder::kPNG_Type, 100);
534 }
535 }
536
reed@android.com8a1c16f2008-12-17 15:59:43 +0000537 switch (fCanvasType) {
538 case kRaster_CanvasType:
539 break;
540 case kPicture_CanvasType:
reed@android.comaefd2bc2009-03-30 21:02:14 +0000541 if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000542 SkPicture* pict = new SkPicture(*fPicture);
543 fPicture->unref();
544 orig->drawPicture(*pict);
545 pict->unref();
reed@android.comaefd2bc2009-03-30 21:02:14 +0000546 } else if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000547 SkDynamicMemoryWStream ostream;
548 fPicture->serialize(&ostream);
549 fPicture->unref();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000550
reed@android.com8a1c16f2008-12-17 15:59:43 +0000551 SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
552 SkPicture pict(&istream);
553 orig->drawPicture(pict);
554 } else {
555 fPicture->draw(orig);
556 fPicture->unref();
557 }
558 fPicture = NULL;
559 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000560#ifdef SK_SUPPORT_GL
reed@android.comf2b98d62010-12-20 18:26:13 +0000561 case kGPU_CanvasType:
562 delete fGpuCanvas;
563 fGpuCanvas = NULL;
564 presentGL();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000565 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000566#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000567 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000568
reed@android.com8a1c16f2008-12-17 15:59:43 +0000569// if ((fScrollTestX | fScrollTestY) != 0)
reed@android.comf2b98d62010-12-20 18:26:13 +0000570 if (false) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000571 const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
572 int dx = fScrollTestX * 7;
573 int dy = fScrollTestY * 7;
574 SkIRect r;
575 SkRegion inval;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000576
reed@android.com8a1c16f2008-12-17 15:59:43 +0000577 r.set(50, 50, 50+100, 50+100);
578 bm.scrollRect(&r, dx, dy, &inval);
579 paint_rgn(bm, r, inval);
580 }
581}
582
reed@android.com6c5f6f22009-08-14 16:08:38 +0000583void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
584 if (fScale) {
585 SkScalar scale = SK_Scalar1 * 7 / 10;
586 SkScalar cx = this->width() / 2;
587 SkScalar cy = this->height() / 2;
588 canvas->translate(cx, cy);
589 canvas->scale(scale, scale);
590 canvas->translate(-cx, -cy);
591 }
592 if (fRotate) {
593 SkScalar cx = this->width() / 2;
594 SkScalar cy = this->height() / 2;
595 canvas->translate(cx, cy);
596 canvas->rotate(SkIntToScalar(30));
597 canvas->translate(-cx, -cy);
598 }
reed@google.comf0b5f682011-03-11 20:08:25 +0000599
600 if (LCDTextDrawFilter::kNeutral_Mode != fLCDMode) {
601 canvas->setDrawFilter(new LCDTextDrawFilter(fLCDMode))->unref();
602 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000603}
604
605void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
reed@google.comf0b5f682011-03-11 20:08:25 +0000606 canvas->setDrawFilter(NULL);
reed@android.com6c5f6f22009-08-14 16:08:38 +0000607}
608
reed@android.com8a1c16f2008-12-17 15:59:43 +0000609static SkBitmap::Config gConfigCycle[] = {
610 SkBitmap::kNo_Config, // none -> none
611 SkBitmap::kNo_Config, // a1 -> none
612 SkBitmap::kNo_Config, // a8 -> none
613 SkBitmap::kNo_Config, // index8 -> none
614 SkBitmap::kARGB_4444_Config, // 565 -> 4444
615 SkBitmap::kARGB_8888_Config, // 4444 -> 8888
616 SkBitmap::kRGB_565_Config // 8888 -> 565
617};
618
619static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
620 return gConfigCycle[c];
621}
622
623bool SampleWindow::nextSample() {
reed@android.com34245c72009-11-03 04:00:48 +0000624 fCurrIndex = (fCurrIndex + 1) % fSamples.count();
625 this->loadView(fSamples[fCurrIndex]());
626 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000627}
628
629bool SampleWindow::onEvent(const SkEvent& evt) {
630 if (evt.isType(ANIMATING_EVENTTYPE)) {
631 if (fAnimating) {
632 this->nextSample();
633 this->postAnimatingEvent();
634 }
635 return true;
636 }
reed@android.com34245c72009-11-03 04:00:48 +0000637 if (evt.isType("set-curr-index")) {
638 fCurrIndex = evt.getFast32() % fSamples.count();
639 this->loadView(fSamples[fCurrIndex]());
640 return true;
641 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000642 return this->INHERITED::onEvent(evt);
643}
644
reed@android.comf2b98d62010-12-20 18:26:13 +0000645bool SampleWindow::onQuery(SkEvent* query) {
646 if (query->isType("get-slide-count")) {
647 query->setFast32(fSamples.count());
648 return true;
649 }
650 if (query->isType("get-slide-title")) {
651 SkView* view = fSamples[query->getFast32()]();
652 SkEvent evt(gTitleEvtName);
653 if (view->doQuery(&evt)) {
654 query->setString("title", evt.findString(gTitleEvtName));
655 }
656 SkSafeUnref(view);
657 return true;
658 }
659 if (query->isType("use-fast-text")) {
660 SkEvent evt(gFastTextEvtName);
661 return curr_view(this)->doQuery(&evt);
662 }
663 return this->INHERITED::onQuery(query);
664}
665
reed@android.com0ae6b242008-12-23 16:49:54 +0000666static void cleanup_for_filename(SkString* name) {
667 char* str = name->writable_str();
reed@android.come191b162009-12-18 21:33:39 +0000668 for (size_t i = 0; i < name->size(); i++) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000669 switch (str[i]) {
670 case ':': str[i] = '-'; break;
671 case '/': str[i] = '-'; break;
672 case ' ': str[i] = '_'; break;
673 default: break;
674 }
675 }
676}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000677
678bool SampleWindow::onHandleChar(SkUnichar uni) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000679 {
680 SkView* view = curr_view(this);
681 if (view) {
682 SkEvent evt(gCharEvtName);
683 evt.setFast32(uni);
684 if (view->doQuery(&evt)) {
685 return true;
686 }
687 }
688 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000689
reed@android.com8a1c16f2008-12-17 15:59:43 +0000690 int dx = 0xFF;
691 int dy = 0xFF;
692
693 switch (uni) {
694 case '5': dx = 0; dy = 0; break;
695 case '8': dx = 0; dy = -1; break;
696 case '6': dx = 1; dy = 0; break;
697 case '2': dx = 0; dy = 1; break;
698 case '4': dx = -1; dy = 0; break;
699 case '7': dx = -1; dy = -1; break;
700 case '9': dx = 1; dy = -1; break;
701 case '3': dx = 1; dy = 1; break;
702 case '1': dx = -1; dy = 1; break;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000703
reed@android.com8a1c16f2008-12-17 15:59:43 +0000704 default:
705 break;
706 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000707
reed@android.com8a1c16f2008-12-17 15:59:43 +0000708 if (0xFF != dx && 0xFF != dy) {
709 if ((dx | dy) == 0) {
710 fScrollTestX = fScrollTestY = 0;
711 } else {
712 fScrollTestX += dx;
713 fScrollTestY += dy;
714 }
715 this->inval(NULL);
716 return true;
717 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000718
reed@android.com0ae6b242008-12-23 16:49:54 +0000719 switch (uni) {
720 case 'a':
721 fAnimating = !fAnimating;
722 this->postAnimatingEvent();
723 this->updateTitle();
724 return true;
725 case 'f': {
726 const char* title = this->getTitle();
727 if (title[0] == 0) {
728 title = "sampleapp";
729 }
730 SkString name(title);
731 cleanup_for_filename(&name);
732 name.append(".png");
733 if (SkImageEncoder::EncodeFile(name.c_str(), this->getBitmap(),
reed@android.comb08eb2b2009-01-06 20:16:26 +0000734 SkImageEncoder::kPNG_Type, 100)) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000735 SkDebugf("Created %s\n", name.c_str());
736 }
737 return true;
738 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000739 case 'r':
740 fRotate = !fRotate;
741 this->inval(NULL);
742 this->updateTitle();
743 return true;
744 case 's':
745 fScale = !fScale;
746 this->inval(NULL);
747 this->updateTitle();
748 return true;
reed@google.comfb56a9e2011-02-10 18:47:24 +0000749 case 'c':
750 fUseClip = !fUseClip;
751 this->inval(NULL);
752 this->updateTitle();
753 return true;
reed@android.comf2b98d62010-12-20 18:26:13 +0000754 case 'd':
755 SkGraphics::SetFontCacheUsed(0);
756 return true;
757 case 'g':
758 fRequestGrabImage = true;
759 this->inval(NULL);
760 break;
reed@google.comf0b5f682011-03-11 20:08:25 +0000761 case 'l':
762 fLCDMode = cycle_lcdmode(fLCDMode);
763 this->updateTitle();
764 this->inval(NULL);
765 break;
reed@android.com0ae6b242008-12-23 16:49:54 +0000766 default:
767 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000768 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000769
reed@android.com8a1c16f2008-12-17 15:59:43 +0000770 return this->INHERITED::onHandleChar(uni);
771}
772
773#include "SkDumpCanvas.h"
774
775bool SampleWindow::onHandleKey(SkKey key) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000776 {
777 SkView* view = curr_view(this);
778 if (view) {
779 SkEvent evt(gKeyEvtName);
780 evt.setFast32(key);
781 if (view->doQuery(&evt)) {
782 return true;
783 }
784 }
785 }
786
reed@android.com8a1c16f2008-12-17 15:59:43 +0000787 switch (key) {
788 case kRight_SkKey:
789 if (this->nextSample()) {
790 return true;
791 }
792 break;
793 case kLeft_SkKey:
794 fCanvasType = cycle_canvastype(fCanvasType);
795 this->updateTitle();
796 this->inval(NULL);
797 return true;
798 case kUp_SkKey:
reed@android.come522ca52009-11-23 20:10:41 +0000799 fNClip = !fNClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000800 this->updateTitle();
801 this->inval(NULL);
802 return true;
803 case kDown_SkKey:
804 this->setConfig(cycle_configs(this->getBitmap().config()));
805 this->updateTitle();
806 return true;
807 case kOK_SkKey:
reed@android.comf2b98d62010-12-20 18:26:13 +0000808 if (false) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000809 SkDebugfDumper dumper;
810 SkDumpCanvas dc(&dumper);
811 this->draw(&dc);
812 } else {
813 fRepeatDrawing = !fRepeatDrawing;
814 if (fRepeatDrawing) {
815 this->inval(NULL);
816 }
817 }
818 return true;
reed@android.com34245c72009-11-03 04:00:48 +0000819 case kBack_SkKey:
820 this->loadView(NULL);
821 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000822 default:
823 break;
824 }
825 return this->INHERITED::onHandleKey(key);
826}
827
828void SampleWindow::loadView(SkView* view) {
829 SkView::F2BIter iter(this);
830 SkView* prev = iter.next();
831 if (prev) {
832 prev->detachFromParent();
833 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000834
reed@android.com34245c72009-11-03 04:00:48 +0000835 if (NULL == view) {
836 view = create_overview(fSamples.count(), fSamples.begin());
837 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000838 view->setVisibleP(true);
reed@android.comf2b98d62010-12-20 18:26:13 +0000839 view->setClipToBounds(false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000840 this->attachChildToFront(view)->unref();
841 view->setSize(this->width(), this->height());
842
843 this->updateTitle();
844}
845
846static const char* gConfigNames[] = {
847 "unknown config",
848 "A1",
849 "A8",
850 "Index8",
851 "565",
852 "4444",
853 "8888"
854};
855
856static const char* configToString(SkBitmap::Config c) {
857 return gConfigNames[c];
858}
859
860static const char* gCanvasTypePrefix[] = {
861 "raster: ",
862 "picture: ",
863 "opengl: "
864};
865
866void SampleWindow::updateTitle() {
867 SkString title;
868
869 SkView::F2BIter iter(this);
870 SkView* view = iter.next();
871 SkEvent evt(gTitleEvtName);
872 if (view->doQuery(&evt)) {
873 title.set(evt.findString(gTitleEvtName));
874 }
875 if (title.size() == 0) {
876 title.set("<unknown>");
877 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000878
reed@android.com8a1c16f2008-12-17 15:59:43 +0000879 title.prepend(gCanvasTypePrefix[fCanvasType]);
880
881 title.prepend(" ");
882 title.prepend(configToString(this->getBitmap().config()));
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000883
reed@android.com8a1c16f2008-12-17 15:59:43 +0000884 if (fAnimating) {
885 title.prepend("<A> ");
886 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000887 if (fScale) {
888 title.prepend("<S> ");
889 }
890 if (fRotate) {
891 title.prepend("<R> ");
892 }
reed@android.come522ca52009-11-23 20:10:41 +0000893 if (fNClip) {
894 title.prepend("<C> ");
895 }
reed@google.comf0b5f682011-03-11 20:08:25 +0000896 if (LCDTextDrawFilter::kForceOn_Mode == fLCDMode) {
897 title.prepend("LCD ");
898 } else if (LCDTextDrawFilter::kForceOff_Mode == fLCDMode) {
899 title.prepend("lcd ");
900 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000901 this->setTitle(title.c_str());
902}
903
904void SampleWindow::onSizeChange() {
905 this->INHERITED::onSizeChange();
906
907 SkView::F2BIter iter(this);
908 SkView* view = iter.next();
909 view->setSize(this->width(), this->height());
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000910
reed@android.com8a1c16f2008-12-17 15:59:43 +0000911 // rebuild our clippath
912 {
913 const SkScalar W = this->width();
914 const SkScalar H = this->height();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000915
reed@android.com8a1c16f2008-12-17 15:59:43 +0000916 fClipPath.reset();
917#if 0
918 for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
919 SkRect r;
920 r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
921 for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
922 fClipPath.addRect(r);
923 }
924#else
925 SkRect r;
926 r.set(0, 0, W, H);
927 fClipPath.addRect(r, SkPath::kCCW_Direction);
928 r.set(W/4, H/4, W*3/4, H*3/4);
929 fClipPath.addRect(r, SkPath::kCW_Direction);
930#endif
931 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000932
reed@android.com8a1c16f2008-12-17 15:59:43 +0000933 this->updateTitle(); // to refresh our config
934}
935
936///////////////////////////////////////////////////////////////////////////////
937
reed@android.comf2b98d62010-12-20 18:26:13 +0000938template <typename T> void SkTBSort(T array[], int count) {
939 for (int i = 1; i < count - 1; i++) {
940 bool didSwap = false;
941 for (int j = count - 1; j > i; --j) {
942 if (array[j] < array[j-1]) {
943 T tmp(array[j-1]);
944 array[j-1] = array[j];
945 array[j] = tmp;
946 didSwap = true;
947 }
948 }
949 if (!didSwap) {
950 break;
951 }
952 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000953
reed@android.comf2b98d62010-12-20 18:26:13 +0000954 for (int k = 0; k < count - 1; k++) {
955 SkASSERT(!(array[k+1] < array[k]));
956 }
957}
958
959#include "SkRandom.h"
960
961static void rand_rect(SkIRect* rect, SkRandom& rand) {
962 int bits = 8;
963 int shift = 32 - bits;
964 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
965 rand.nextU() >> shift, rand.nextU() >> shift);
966 rect->sort();
967}
968
969static void dumpRect(const SkIRect& r) {
970 SkDebugf(" { %d, %d, %d, %d },\n",
971 r.fLeft, r.fTop,
972 r.fRight, r.fBottom);
973}
974
975static void test_rects(const SkIRect rect[], int count) {
976 SkRegion rgn0, rgn1;
977
978 for (int i = 0; i < count; i++) {
979 rgn0.op(rect[i], SkRegion::kUnion_Op);
980 // dumpRect(rect[i]);
981 }
982 rgn1.setRects(rect, count);
983
984 if (rgn0 != rgn1) {
985 SkDebugf("\n");
986 for (int i = 0; i < count; i++) {
987 dumpRect(rect[i]);
988 }
989 SkDebugf("\n");
990 }
991}
992
993static void test() {
994 size_t i;
995
996 const SkIRect r0[] = {
997 { 0, 0, 1, 1 },
998 { 2, 2, 3, 3 },
999 };
1000 const SkIRect r1[] = {
1001 { 0, 0, 1, 3 },
1002 { 1, 1, 2, 2 },
1003 { 2, 0, 3, 3 },
1004 };
1005 const SkIRect r2[] = {
1006 { 0, 0, 1, 2 },
1007 { 2, 1, 3, 3 },
1008 { 4, 0, 5, 1 },
1009 { 6, 0, 7, 4 },
1010 };
1011
1012 static const struct {
1013 const SkIRect* fRects;
1014 int fCount;
1015 } gRecs[] = {
1016 { r0, SK_ARRAY_COUNT(r0) },
1017 { r1, SK_ARRAY_COUNT(r1) },
1018 { r2, SK_ARRAY_COUNT(r2) },
1019 };
1020
1021 for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
1022 test_rects(gRecs[i].fRects, gRecs[i].fCount);
1023 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +00001024
reed@android.comf2b98d62010-12-20 18:26:13 +00001025 SkRandom rand;
1026 for (i = 0; i < 10000; i++) {
1027 SkRegion rgn0, rgn1;
1028
1029 const int N = 8;
1030 SkIRect rect[N];
1031 for (int j = 0; j < N; j++) {
1032 rand_rect(&rect[j], rand);
1033 }
1034 test_rects(rect, N);
1035 }
1036}
1037
reed@android.com8a1c16f2008-12-17 15:59:43 +00001038SkOSWindow* create_sk_window(void* hwnd) {
reed@android.comf2b98d62010-12-20 18:26:13 +00001039// test();
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001040 return new SampleWindow(hwnd);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001041}
1042
1043void get_preferred_size(int* x, int* y, int* width, int* height) {
1044 *x = 10;
1045 *y = 50;
1046 *width = 640;
1047 *height = 480;
1048}
1049
1050void application_init() {
1051// setenv("ANDROID_ROOT", "../../../data", 0);
reed@android.come191b162009-12-18 21:33:39 +00001052#ifdef SK_BUILD_FOR_MAC
reed@android.com8a1c16f2008-12-17 15:59:43 +00001053 setenv("ANDROID_ROOT", "/android/device/data", 0);
reed@android.come191b162009-12-18 21:33:39 +00001054#endif
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001055 SkGraphics::Init();
1056 SkEvent::Init();
reed@android.com8a1c16f2008-12-17 15:59:43 +00001057}
1058
1059void application_term() {
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001060 SkEvent::Term();
1061 SkGraphics::Term();
reed@android.com8a1c16f2008-12-17 15:59:43 +00001062}