blob: 23ee27fb3f84619f43f8231ace0cfdce5aface2e [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
reed@google.comf0b5f682011-03-11 20:08:25 +000044#if 1
45#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
352 testpdf();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000353}
354
355SampleWindow::~SampleWindow() {
356 delete fPicture;
reed@android.comf2b98d62010-12-20 18:26:13 +0000357 delete fGpuCanvas;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000358 if (NULL != fGrContext) {
359 fGrContext->unref();
360 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000361}
362
reed@android.com55e76b22009-11-23 21:46:47 +0000363static SkBitmap capture_bitmap(SkCanvas* canvas) {
364 SkBitmap bm;
365 const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
366 src.copyTo(&bm, src.config());
367 return bm;
368}
369
370static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
371 SkBitmap* diff) {
372 const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000373
reed@android.com55e76b22009-11-23 21:46:47 +0000374 SkAutoLockPixels alp0(src);
375 SkAutoLockPixels alp1(orig);
376 for (int y = 0; y < src.height(); y++) {
377 const void* srcP = src.getAddr(0, y);
378 const void* origP = orig.getAddr(0, y);
379 size_t bytes = src.width() * src.bytesPerPixel();
380 if (memcmp(srcP, origP, bytes)) {
381 SkDebugf("---------- difference on line %d\n", y);
382 return true;
383 }
384 }
385 return false;
386}
387
reed@android.com44177402009-11-23 21:07:51 +0000388#define XCLIP_N 8
389#define YCLIP_N 8
reed@android.come522ca52009-11-23 20:10:41 +0000390
391void SampleWindow::draw(SkCanvas* canvas) {
reed@android.com44177402009-11-23 21:07:51 +0000392 // update the animation time
reed@android.comf2b98d62010-12-20 18:26:13 +0000393 gAnimTimePrev = gAnimTime;
reed@android.com44177402009-11-23 21:07:51 +0000394 gAnimTime = SkTime::GetMSecs();
395
reed@android.come522ca52009-11-23 20:10:41 +0000396 if (fNClip) {
reed@android.com55e76b22009-11-23 21:46:47 +0000397 this->INHERITED::draw(canvas);
398 SkBitmap orig = capture_bitmap(canvas);
reed@android.come522ca52009-11-23 20:10:41 +0000399
400 const SkScalar w = this->width();
401 const SkScalar h = this->height();
402 const SkScalar cw = w / XCLIP_N;
403 const SkScalar ch = h / YCLIP_N;
404 for (int y = 0; y < YCLIP_N; y++) {
reed@android.com55e76b22009-11-23 21:46:47 +0000405 SkRect r;
406 r.fTop = y * ch;
407 r.fBottom = (y + 1) * ch;
408 if (y == YCLIP_N - 1) {
409 r.fBottom = h;
410 }
reed@android.come522ca52009-11-23 20:10:41 +0000411 for (int x = 0; x < XCLIP_N; x++) {
412 SkAutoCanvasRestore acr(canvas, true);
reed@android.com55e76b22009-11-23 21:46:47 +0000413 r.fLeft = x * cw;
414 r.fRight = (x + 1) * cw;
415 if (x == XCLIP_N - 1) {
416 r.fRight = w;
417 }
reed@android.come522ca52009-11-23 20:10:41 +0000418 canvas->clipRect(r);
419 this->INHERITED::draw(canvas);
420 }
421 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000422
reed@android.com55e76b22009-11-23 21:46:47 +0000423 SkBitmap diff;
424 if (bitmap_diff(canvas, orig, &diff)) {
425 }
reed@android.come522ca52009-11-23 20:10:41 +0000426 } else {
427 this->INHERITED::draw(canvas);
428 }
429}
430
reed@android.com8a1c16f2008-12-17 15:59:43 +0000431void SampleWindow::onDraw(SkCanvas* canvas) {
432 if (fRepeatDrawing) {
433 this->inval(NULL);
434 }
435}
436
437#include "SkColorPriv.h"
438
439static void reverseRedAndBlue(const SkBitmap& bm) {
440 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
441 uint8_t* p = (uint8_t*)bm.getPixels();
442 uint8_t* stop = p + bm.getSize();
443 while (p < stop) {
444 // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
445 unsigned scale = SkAlpha255To256(p[3]);
446 unsigned r = p[2];
447 unsigned b = p[0];
448 p[0] = SkAlphaMul(r, scale);
449 p[1] = SkAlphaMul(p[1], scale);
450 p[2] = SkAlphaMul(b, scale);
451 p += 4;
452 }
453}
454
455SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000456 SkIPoint viewport;
457 bool alreadyGPU = canvas->getViewport(&viewport);
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000458
reed@android.comf2b98d62010-12-20 18:26:13 +0000459 if (kGPU_CanvasType != fCanvasType) {
reed@android.com6efdc472008-12-19 18:24:35 +0000460#ifdef SK_SUPPORT_GL
reed@android.comf2b98d62010-12-20 18:26:13 +0000461 detachGL();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000462#endif
reed@android.comf2b98d62010-12-20 18:26:13 +0000463 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000464
reed@android.com8a1c16f2008-12-17 15:59:43 +0000465 switch (fCanvasType) {
466 case kRaster_CanvasType:
467 canvas = this->INHERITED::beforeChildren(canvas);
468 break;
469 case kPicture_CanvasType:
470 fPicture = new SkPicture;
471 canvas = fPicture->beginRecording(9999, 9999);
472 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000473 case kGPU_CanvasType: {
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000474 if (!alreadyGPU && make3DReady()) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000475 SkDevice* device = canvas->getDevice();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000476 const SkBitmap& bitmap = device->accessBitmap(true);
477
bsalomon@google.com5782d712011-01-21 21:03:59 +0000478 GrRenderTarget* renderTarget;
479 renderTarget = fGrContext->createRenderTargetFrom3DApiState();
480 fGpuCanvas = new SkGpuCanvas(fGrContext, renderTarget);
481 renderTarget->unref();
482
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +0000483 device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
484 bitmap.width(), bitmap.height(),
485 false, false);
reed@google.comac10a2d2010-12-22 21:39:39 +0000486 fGpuCanvas->setDevice(device)->unref();
reed@android.comf2b98d62010-12-20 18:26:13 +0000487 canvas = fGpuCanvas;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000488
reed@android.comf2b98d62010-12-20 18:26:13 +0000489 } else {
490 canvas = this->INHERITED::beforeChildren(canvas);
491 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000492 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000493 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000494 }
495
496 if (fUseClip) {
497 canvas->drawColor(0xFFFF88FF);
498 canvas->clipPath(fClipPath);
499 }
500
501 return canvas;
502}
503
504static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
505 const SkRegion& rgn) {
506 SkCanvas canvas(bm);
507 SkRegion inval(rgn);
508
509 inval.translate(r.fLeft, r.fTop);
510 canvas.clipRegion(inval);
511 canvas.drawColor(0xFFFF8080);
512}
513
514void SampleWindow::afterChildren(SkCanvas* orig) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000515 if (fRequestGrabImage) {
516 fRequestGrabImage = false;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000517
reed@android.comf2b98d62010-12-20 18:26:13 +0000518 SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig;
519 SkDevice* device = canvas->getDevice();
520 SkBitmap bitmap;
reed@google.com5ba2d5b2011-03-10 19:40:34 +0000521 SkIRect bounds = {
522 0, 0,
523 SkScalarRound(this->width()),
524 SkScalarRound(this->height())
525 };
reed@android.comf2b98d62010-12-20 18:26:13 +0000526 if (device->readPixels(bounds, &bitmap)) {
527 static int gSampleGrabCounter;
528 SkString name;
529 name.printf("sample_grab_%d", gSampleGrabCounter++);
530 SkImageEncoder::EncodeFile(name.c_str(), bitmap,
531 SkImageEncoder::kPNG_Type, 100);
532 }
533 }
534
reed@android.com8a1c16f2008-12-17 15:59:43 +0000535 switch (fCanvasType) {
536 case kRaster_CanvasType:
537 break;
538 case kPicture_CanvasType:
reed@android.comaefd2bc2009-03-30 21:02:14 +0000539 if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000540 SkPicture* pict = new SkPicture(*fPicture);
541 fPicture->unref();
542 orig->drawPicture(*pict);
543 pict->unref();
reed@android.comaefd2bc2009-03-30 21:02:14 +0000544 } else if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000545 SkDynamicMemoryWStream ostream;
546 fPicture->serialize(&ostream);
547 fPicture->unref();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000548
reed@android.com8a1c16f2008-12-17 15:59:43 +0000549 SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
550 SkPicture pict(&istream);
551 orig->drawPicture(pict);
552 } else {
553 fPicture->draw(orig);
554 fPicture->unref();
555 }
556 fPicture = NULL;
557 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000558#ifdef SK_SUPPORT_GL
reed@android.comf2b98d62010-12-20 18:26:13 +0000559 case kGPU_CanvasType:
560 delete fGpuCanvas;
561 fGpuCanvas = NULL;
562 presentGL();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000563 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000564#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000565 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000566
reed@android.com8a1c16f2008-12-17 15:59:43 +0000567// if ((fScrollTestX | fScrollTestY) != 0)
reed@android.comf2b98d62010-12-20 18:26:13 +0000568 if (false) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000569 const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
570 int dx = fScrollTestX * 7;
571 int dy = fScrollTestY * 7;
572 SkIRect r;
573 SkRegion inval;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000574
reed@android.com8a1c16f2008-12-17 15:59:43 +0000575 r.set(50, 50, 50+100, 50+100);
576 bm.scrollRect(&r, dx, dy, &inval);
577 paint_rgn(bm, r, inval);
578 }
579}
580
reed@android.com6c5f6f22009-08-14 16:08:38 +0000581void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
582 if (fScale) {
583 SkScalar scale = SK_Scalar1 * 7 / 10;
584 SkScalar cx = this->width() / 2;
585 SkScalar cy = this->height() / 2;
586 canvas->translate(cx, cy);
587 canvas->scale(scale, scale);
588 canvas->translate(-cx, -cy);
589 }
590 if (fRotate) {
591 SkScalar cx = this->width() / 2;
592 SkScalar cy = this->height() / 2;
593 canvas->translate(cx, cy);
594 canvas->rotate(SkIntToScalar(30));
595 canvas->translate(-cx, -cy);
596 }
reed@google.comf0b5f682011-03-11 20:08:25 +0000597
598 if (LCDTextDrawFilter::kNeutral_Mode != fLCDMode) {
599 canvas->setDrawFilter(new LCDTextDrawFilter(fLCDMode))->unref();
600 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000601}
602
603void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
reed@google.comf0b5f682011-03-11 20:08:25 +0000604 canvas->setDrawFilter(NULL);
reed@android.com6c5f6f22009-08-14 16:08:38 +0000605}
606
reed@android.com8a1c16f2008-12-17 15:59:43 +0000607static SkBitmap::Config gConfigCycle[] = {
608 SkBitmap::kNo_Config, // none -> none
609 SkBitmap::kNo_Config, // a1 -> none
610 SkBitmap::kNo_Config, // a8 -> none
611 SkBitmap::kNo_Config, // index8 -> none
612 SkBitmap::kARGB_4444_Config, // 565 -> 4444
613 SkBitmap::kARGB_8888_Config, // 4444 -> 8888
614 SkBitmap::kRGB_565_Config // 8888 -> 565
615};
616
617static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
618 return gConfigCycle[c];
619}
620
621bool SampleWindow::nextSample() {
reed@android.com34245c72009-11-03 04:00:48 +0000622 fCurrIndex = (fCurrIndex + 1) % fSamples.count();
623 this->loadView(fSamples[fCurrIndex]());
624 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000625}
626
627bool SampleWindow::onEvent(const SkEvent& evt) {
628 if (evt.isType(ANIMATING_EVENTTYPE)) {
629 if (fAnimating) {
630 this->nextSample();
631 this->postAnimatingEvent();
632 }
633 return true;
634 }
reed@android.com34245c72009-11-03 04:00:48 +0000635 if (evt.isType("set-curr-index")) {
636 fCurrIndex = evt.getFast32() % fSamples.count();
637 this->loadView(fSamples[fCurrIndex]());
638 return true;
639 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000640 return this->INHERITED::onEvent(evt);
641}
642
reed@android.comf2b98d62010-12-20 18:26:13 +0000643bool SampleWindow::onQuery(SkEvent* query) {
644 if (query->isType("get-slide-count")) {
645 query->setFast32(fSamples.count());
646 return true;
647 }
648 if (query->isType("get-slide-title")) {
649 SkView* view = fSamples[query->getFast32()]();
650 SkEvent evt(gTitleEvtName);
651 if (view->doQuery(&evt)) {
652 query->setString("title", evt.findString(gTitleEvtName));
653 }
654 SkSafeUnref(view);
655 return true;
656 }
657 if (query->isType("use-fast-text")) {
658 SkEvent evt(gFastTextEvtName);
659 return curr_view(this)->doQuery(&evt);
660 }
661 return this->INHERITED::onQuery(query);
662}
663
reed@android.com0ae6b242008-12-23 16:49:54 +0000664static void cleanup_for_filename(SkString* name) {
665 char* str = name->writable_str();
reed@android.come191b162009-12-18 21:33:39 +0000666 for (size_t i = 0; i < name->size(); i++) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000667 switch (str[i]) {
668 case ':': str[i] = '-'; break;
669 case '/': str[i] = '-'; break;
670 case ' ': str[i] = '_'; break;
671 default: break;
672 }
673 }
674}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000675
676bool SampleWindow::onHandleChar(SkUnichar uni) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000677 {
678 SkView* view = curr_view(this);
679 if (view) {
680 SkEvent evt(gCharEvtName);
681 evt.setFast32(uni);
682 if (view->doQuery(&evt)) {
683 return true;
684 }
685 }
686 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000687
reed@android.com8a1c16f2008-12-17 15:59:43 +0000688 int dx = 0xFF;
689 int dy = 0xFF;
690
691 switch (uni) {
692 case '5': dx = 0; dy = 0; break;
693 case '8': dx = 0; dy = -1; break;
694 case '6': dx = 1; dy = 0; break;
695 case '2': dx = 0; dy = 1; break;
696 case '4': dx = -1; dy = 0; break;
697 case '7': dx = -1; dy = -1; break;
698 case '9': dx = 1; dy = -1; break;
699 case '3': dx = 1; dy = 1; break;
700 case '1': dx = -1; dy = 1; break;
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000701
reed@android.com8a1c16f2008-12-17 15:59:43 +0000702 default:
703 break;
704 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000705
reed@android.com8a1c16f2008-12-17 15:59:43 +0000706 if (0xFF != dx && 0xFF != dy) {
707 if ((dx | dy) == 0) {
708 fScrollTestX = fScrollTestY = 0;
709 } else {
710 fScrollTestX += dx;
711 fScrollTestY += dy;
712 }
713 this->inval(NULL);
714 return true;
715 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000716
reed@android.com0ae6b242008-12-23 16:49:54 +0000717 switch (uni) {
718 case 'a':
719 fAnimating = !fAnimating;
720 this->postAnimatingEvent();
721 this->updateTitle();
722 return true;
723 case 'f': {
724 const char* title = this->getTitle();
725 if (title[0] == 0) {
726 title = "sampleapp";
727 }
728 SkString name(title);
729 cleanup_for_filename(&name);
730 name.append(".png");
731 if (SkImageEncoder::EncodeFile(name.c_str(), this->getBitmap(),
reed@android.comb08eb2b2009-01-06 20:16:26 +0000732 SkImageEncoder::kPNG_Type, 100)) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000733 SkDebugf("Created %s\n", name.c_str());
734 }
735 return true;
736 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000737 case 'r':
738 fRotate = !fRotate;
739 this->inval(NULL);
740 this->updateTitle();
741 return true;
742 case 's':
743 fScale = !fScale;
744 this->inval(NULL);
745 this->updateTitle();
746 return true;
reed@google.comfb56a9e2011-02-10 18:47:24 +0000747 case 'c':
748 fUseClip = !fUseClip;
749 this->inval(NULL);
750 this->updateTitle();
751 return true;
reed@android.comf2b98d62010-12-20 18:26:13 +0000752 case 'd':
753 SkGraphics::SetFontCacheUsed(0);
754 return true;
755 case 'g':
756 fRequestGrabImage = true;
757 this->inval(NULL);
758 break;
reed@google.comf0b5f682011-03-11 20:08:25 +0000759 case 'l':
760 fLCDMode = cycle_lcdmode(fLCDMode);
761 this->updateTitle();
762 this->inval(NULL);
763 break;
reed@android.com0ae6b242008-12-23 16:49:54 +0000764 default:
765 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000766 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000767
reed@android.com8a1c16f2008-12-17 15:59:43 +0000768 return this->INHERITED::onHandleChar(uni);
769}
770
771#include "SkDumpCanvas.h"
772
773bool SampleWindow::onHandleKey(SkKey key) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000774 {
775 SkView* view = curr_view(this);
776 if (view) {
777 SkEvent evt(gKeyEvtName);
778 evt.setFast32(key);
779 if (view->doQuery(&evt)) {
780 return true;
781 }
782 }
783 }
784
reed@android.com8a1c16f2008-12-17 15:59:43 +0000785 switch (key) {
786 case kRight_SkKey:
787 if (this->nextSample()) {
788 return true;
789 }
790 break;
791 case kLeft_SkKey:
792 fCanvasType = cycle_canvastype(fCanvasType);
793 this->updateTitle();
794 this->inval(NULL);
795 return true;
796 case kUp_SkKey:
reed@android.come522ca52009-11-23 20:10:41 +0000797 fNClip = !fNClip;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000798 this->updateTitle();
799 this->inval(NULL);
800 return true;
801 case kDown_SkKey:
802 this->setConfig(cycle_configs(this->getBitmap().config()));
803 this->updateTitle();
804 return true;
805 case kOK_SkKey:
reed@android.comf2b98d62010-12-20 18:26:13 +0000806 if (false) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000807 SkDebugfDumper dumper;
808 SkDumpCanvas dc(&dumper);
809 this->draw(&dc);
810 } else {
811 fRepeatDrawing = !fRepeatDrawing;
812 if (fRepeatDrawing) {
813 this->inval(NULL);
814 }
815 }
816 return true;
reed@android.com34245c72009-11-03 04:00:48 +0000817 case kBack_SkKey:
818 this->loadView(NULL);
819 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000820 default:
821 break;
822 }
823 return this->INHERITED::onHandleKey(key);
824}
825
826void SampleWindow::loadView(SkView* view) {
827 SkView::F2BIter iter(this);
828 SkView* prev = iter.next();
829 if (prev) {
830 prev->detachFromParent();
831 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000832
reed@android.com34245c72009-11-03 04:00:48 +0000833 if (NULL == view) {
834 view = create_overview(fSamples.count(), fSamples.begin());
835 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000836 view->setVisibleP(true);
reed@android.comf2b98d62010-12-20 18:26:13 +0000837 view->setClipToBounds(false);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000838 this->attachChildToFront(view)->unref();
839 view->setSize(this->width(), this->height());
840
841 this->updateTitle();
842}
843
844static const char* gConfigNames[] = {
845 "unknown config",
846 "A1",
847 "A8",
848 "Index8",
849 "565",
850 "4444",
851 "8888"
852};
853
854static const char* configToString(SkBitmap::Config c) {
855 return gConfigNames[c];
856}
857
858static const char* gCanvasTypePrefix[] = {
859 "raster: ",
860 "picture: ",
861 "opengl: "
862};
863
864void SampleWindow::updateTitle() {
865 SkString title;
866
867 SkView::F2BIter iter(this);
868 SkView* view = iter.next();
869 SkEvent evt(gTitleEvtName);
870 if (view->doQuery(&evt)) {
871 title.set(evt.findString(gTitleEvtName));
872 }
873 if (title.size() == 0) {
874 title.set("<unknown>");
875 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000876
reed@android.com8a1c16f2008-12-17 15:59:43 +0000877 title.prepend(gCanvasTypePrefix[fCanvasType]);
878
879 title.prepend(" ");
880 title.prepend(configToString(this->getBitmap().config()));
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000881
reed@android.com8a1c16f2008-12-17 15:59:43 +0000882 if (fAnimating) {
883 title.prepend("<A> ");
884 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000885 if (fScale) {
886 title.prepend("<S> ");
887 }
888 if (fRotate) {
889 title.prepend("<R> ");
890 }
reed@android.come522ca52009-11-23 20:10:41 +0000891 if (fNClip) {
892 title.prepend("<C> ");
893 }
reed@google.comf0b5f682011-03-11 20:08:25 +0000894 if (LCDTextDrawFilter::kForceOn_Mode == fLCDMode) {
895 title.prepend("LCD ");
896 } else if (LCDTextDrawFilter::kForceOff_Mode == fLCDMode) {
897 title.prepend("lcd ");
898 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000899 this->setTitle(title.c_str());
900}
901
902void SampleWindow::onSizeChange() {
903 this->INHERITED::onSizeChange();
904
905 SkView::F2BIter iter(this);
906 SkView* view = iter.next();
907 view->setSize(this->width(), this->height());
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000908
reed@android.com8a1c16f2008-12-17 15:59:43 +0000909 // rebuild our clippath
910 {
911 const SkScalar W = this->width();
912 const SkScalar H = this->height();
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000913
reed@android.com8a1c16f2008-12-17 15:59:43 +0000914 fClipPath.reset();
915#if 0
916 for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
917 SkRect r;
918 r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
919 for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
920 fClipPath.addRect(r);
921 }
922#else
923 SkRect r;
924 r.set(0, 0, W, H);
925 fClipPath.addRect(r, SkPath::kCCW_Direction);
926 r.set(W/4, H/4, W*3/4, H*3/4);
927 fClipPath.addRect(r, SkPath::kCW_Direction);
928#endif
929 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000930
reed@android.com8a1c16f2008-12-17 15:59:43 +0000931 this->updateTitle(); // to refresh our config
932}
933
934///////////////////////////////////////////////////////////////////////////////
935
reed@android.comf2b98d62010-12-20 18:26:13 +0000936template <typename T> void SkTBSort(T array[], int count) {
937 for (int i = 1; i < count - 1; i++) {
938 bool didSwap = false;
939 for (int j = count - 1; j > i; --j) {
940 if (array[j] < array[j-1]) {
941 T tmp(array[j-1]);
942 array[j-1] = array[j];
943 array[j] = tmp;
944 didSwap = true;
945 }
946 }
947 if (!didSwap) {
948 break;
949 }
950 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +0000951
reed@android.comf2b98d62010-12-20 18:26:13 +0000952 for (int k = 0; k < count - 1; k++) {
953 SkASSERT(!(array[k+1] < array[k]));
954 }
955}
956
957#include "SkRandom.h"
958
959static void rand_rect(SkIRect* rect, SkRandom& rand) {
960 int bits = 8;
961 int shift = 32 - bits;
962 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
963 rand.nextU() >> shift, rand.nextU() >> shift);
964 rect->sort();
965}
966
967static void dumpRect(const SkIRect& r) {
968 SkDebugf(" { %d, %d, %d, %d },\n",
969 r.fLeft, r.fTop,
970 r.fRight, r.fBottom);
971}
972
973static void test_rects(const SkIRect rect[], int count) {
974 SkRegion rgn0, rgn1;
975
976 for (int i = 0; i < count; i++) {
977 rgn0.op(rect[i], SkRegion::kUnion_Op);
978 // dumpRect(rect[i]);
979 }
980 rgn1.setRects(rect, count);
981
982 if (rgn0 != rgn1) {
983 SkDebugf("\n");
984 for (int i = 0; i < count; i++) {
985 dumpRect(rect[i]);
986 }
987 SkDebugf("\n");
988 }
989}
990
991static void test() {
992 size_t i;
993
994 const SkIRect r0[] = {
995 { 0, 0, 1, 1 },
996 { 2, 2, 3, 3 },
997 };
998 const SkIRect r1[] = {
999 { 0, 0, 1, 3 },
1000 { 1, 1, 2, 2 },
1001 { 2, 0, 3, 3 },
1002 };
1003 const SkIRect r2[] = {
1004 { 0, 0, 1, 2 },
1005 { 2, 1, 3, 3 },
1006 { 4, 0, 5, 1 },
1007 { 6, 0, 7, 4 },
1008 };
1009
1010 static const struct {
1011 const SkIRect* fRects;
1012 int fCount;
1013 } gRecs[] = {
1014 { r0, SK_ARRAY_COUNT(r0) },
1015 { r1, SK_ARRAY_COUNT(r1) },
1016 { r2, SK_ARRAY_COUNT(r2) },
1017 };
1018
1019 for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
1020 test_rects(gRecs[i].fRects, gRecs[i].fCount);
1021 }
bsalomon@google.com2e7b43d2011-01-18 20:57:22 +00001022
reed@android.comf2b98d62010-12-20 18:26:13 +00001023 SkRandom rand;
1024 for (i = 0; i < 10000; i++) {
1025 SkRegion rgn0, rgn1;
1026
1027 const int N = 8;
1028 SkIRect rect[N];
1029 for (int j = 0; j < N; j++) {
1030 rand_rect(&rect[j], rand);
1031 }
1032 test_rects(rect, N);
1033 }
1034}
1035
reed@android.com8a1c16f2008-12-17 15:59:43 +00001036SkOSWindow* create_sk_window(void* hwnd) {
reed@android.comf2b98d62010-12-20 18:26:13 +00001037// test();
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001038 return new SampleWindow(hwnd);
reed@android.com8a1c16f2008-12-17 15:59:43 +00001039}
1040
1041void get_preferred_size(int* x, int* y, int* width, int* height) {
1042 *x = 10;
1043 *y = 50;
1044 *width = 640;
1045 *height = 480;
1046}
1047
1048void application_init() {
1049// setenv("ANDROID_ROOT", "../../../data", 0);
reed@android.come191b162009-12-18 21:33:39 +00001050#ifdef SK_BUILD_FOR_MAC
reed@android.com8a1c16f2008-12-17 15:59:43 +00001051 setenv("ANDROID_ROOT", "/android/device/data", 0);
reed@android.come191b162009-12-18 21:33:39 +00001052#endif
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001053 SkGraphics::Init();
1054 SkEvent::Init();
reed@android.com8a1c16f2008-12-17 15:59:43 +00001055}
1056
1057void application_term() {
bsalomon@google.com2fbc7fa2011-01-05 16:34:41 +00001058 SkEvent::Term();
1059 SkGraphics::Term();
reed@android.com8a1c16f2008-12-17 15:59:43 +00001060}