blob: 7ba069cca1a1deb62e46881e4245b57c68d1f6ff [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SkCanvas.h"
2#include "SkDevice.h"
3#include "SkGLCanvas.h"
4#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"
9#include "SkWindow.h"
10
11#include "SampleCode.h"
12
reed@android.com161b00b2009-11-03 15:33:14 +000013#define SHOW_OVERVIEW false
14
reed@android.com34245c72009-11-03 04:00:48 +000015SkView* create_overview(int, const SkViewFactory*);
16
reed@android.com6efdc472008-12-19 18:24:35 +000017//#define SK_SUPPORT_GL
18
19#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +000020#include <AGL/agl.h>
21#include <OpenGL/gl.h>
reed@android.com6efdc472008-12-19 18:24:35 +000022#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000023
24#define ANIMATING_EVENTTYPE "nextSample"
25#define ANIMATING_DELAY 750
26
27#define USE_OFFSCREEN
28
29SkViewRegister* SkViewRegister::gHead;
30SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
31 static bool gOnce;
32 if (!gOnce) {
33 gHead = NULL;
34 gOnce = true;
35 }
36
37 fChain = gHead;
38 gHead = this;
39}
40
reed@android.com6efdc472008-12-19 18:24:35 +000041#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +000042static AGLContext gAGLContext;
43
44static void init_gl(WindowRef wref) {
45 GLint major, minor;
46
47 aglGetVersion(&major, &minor);
48 SkDebugf("---- agl version %d %d\n", major, minor);
49
50 const GLint pixelAttrs[] = {
51 AGL_RGBA,
52 AGL_DEPTH_SIZE, 32,
53 AGL_OFFSCREEN,
54 AGL_NONE
55 };
56
57 AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
58 SkDebugf("----- agl format %p\n", format);
59 gAGLContext = aglCreateContext(format, NULL);
60 SkDebugf("----- agl context %p\n", gAGLContext);
61 aglDestroyPixelFormat(format);
62
63 aglEnable(gAGLContext, GL_BLEND);
64 aglEnable(gAGLContext, GL_LINE_SMOOTH);
65 aglEnable(gAGLContext, GL_POINT_SMOOTH);
66 aglEnable(gAGLContext, GL_POLYGON_SMOOTH);
67
68 aglSetCurrentContext(gAGLContext);
69}
70
71static void setup_offscreen_gl(const SkBitmap& offscreen, WindowRef wref) {
72 GLboolean success = true;
73
74#ifdef USE_OFFSCREEN
75 success = aglSetOffScreen(gAGLContext,
76 offscreen.width(),
77 offscreen.height(),
78 offscreen.rowBytes(),
79 offscreen.getPixels());
80#else
81 success = aglSetWindowRef(gAGLContext, wref);
82#endif
83
84 GLenum err = aglGetError();
85 if (err) {
86 SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
87 aglErrorString(err), offscreen.width(), offscreen.height());
88 }
89
90 glEnable(GL_BLEND);
91 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
92 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
93 glEnable(GL_TEXTURE_2D);
94
95 glClearColor(0, 0, 0, 0);
96 glClear(GL_COLOR_BUFFER_BIT);
97}
reed@android.com6efdc472008-12-19 18:24:35 +000098#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000099
100//////////////////////////////////////////////////////////////////////////////
101
102static const char gTitleEvtName[] = "SampleCode_Title_Event";
103static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
104
105bool SampleCode::TitleQ(const SkEvent& evt) {
106 return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
107}
108
109void SampleCode::TitleR(SkEvent* evt, const char title[]) {
110 SkASSERT(evt && TitleQ(*evt));
111 evt->setString(gTitleEvtName, title);
112}
113
114bool SampleCode::PrefSizeQ(const SkEvent& evt) {
115 return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
116}
117
118void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
119 SkASSERT(evt && PrefSizeQ(*evt));
120 SkScalar size[2];
121 size[0] = width;
122 size[1] = height;
123 evt->setScalars(gPrefSizeEvtName, 2, size);
124}
125
126//////////////////////////////////////////////////////////////////////////////
127
128class SampleWindow : public SkOSWindow {
reed@android.com34245c72009-11-03 04:00:48 +0000129 SkTDArray<SkViewFactory> fSamples;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130public:
131 SampleWindow(void* hwnd);
132 virtual ~SampleWindow();
133
134protected:
135 virtual void onDraw(SkCanvas* canvas);
136 virtual bool onHandleKey(SkKey key);
137 virtual bool onHandleChar(SkUnichar);
138 virtual void onSizeChange();
139
140 virtual SkCanvas* beforeChildren(SkCanvas*);
141 virtual void afterChildren(SkCanvas*);
reed@android.com6c5f6f22009-08-14 16:08:38 +0000142 virtual void beforeChild(SkView* child, SkCanvas* canvas);
143 virtual void afterChild(SkView* child, SkCanvas* canvas);
144
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145 virtual bool onEvent(const SkEvent& evt);
146
147#if 0
148 virtual bool handleChar(SkUnichar uni);
149 virtual bool handleEvent(const SkEvent& evt);
150 virtual bool handleKey(SkKey key);
151 virtual bool handleKeyUp(SkKey key);
152
153 virtual bool onClick(Click* click);
154 virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
155 virtual bool onHandleKeyUp(SkKey key);
156#endif
157private:
reed@android.com34245c72009-11-03 04:00:48 +0000158 int fCurrIndex;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159
160 SkPicture* fPicture;
161 SkGLCanvas* fGLCanvas;
162 SkPath fClipPath;
163
164 enum CanvasType {
165 kRaster_CanvasType,
166 kPicture_CanvasType,
167 kOpenGL_CanvasType
168 };
169 CanvasType fCanvasType;
170
171 bool fUseClip;
172 bool fRepeatDrawing;
173 bool fAnimating;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000174 bool fRotate;
175 bool fScale;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000176
177 int fScrollTestX, fScrollTestY;
178
179 void loadView(SkView*);
180 void updateTitle();
181 bool nextSample();
182
183 void postAnimatingEvent() {
184 if (fAnimating) {
185 SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
186 evt->post(this->getSinkID(), ANIMATING_DELAY);
187 }
188 }
189
190
191 static CanvasType cycle_canvastype(CanvasType);
192
193 typedef SkOSWindow INHERITED;
194};
195
196SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
197 static const CanvasType gCT[] = {
198 kPicture_CanvasType,
199 kOpenGL_CanvasType,
200 kRaster_CanvasType
201 };
202 return gCT[ct];
203}
204
205SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
reed@android.com6efdc472008-12-19 18:24:35 +0000206#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000207 init_gl((WindowRef)hwnd);
reed@android.com6efdc472008-12-19 18:24:35 +0000208#endif
209
reed@android.com8a1c16f2008-12-17 15:59:43 +0000210 fPicture = NULL;
211 fGLCanvas = NULL;
212
213 fCanvasType = kRaster_CanvasType;
214 fUseClip = false;
215 fRepeatDrawing = false;
216 fAnimating = false;
reed@android.com6c5f6f22009-08-14 16:08:38 +0000217 fRotate = false;
218 fScale = false;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219
220 fScrollTestX = fScrollTestY = 0;
221
222// this->setConfig(SkBitmap::kRGB_565_Config);
223 this->setConfig(SkBitmap::kARGB_8888_Config);
224 this->setVisibleP(true);
225
reed@android.com34245c72009-11-03 04:00:48 +0000226 {
227 const SkViewRegister* reg = SkViewRegister::Head();
228 while (reg) {
229 *fSamples.append() = reg->factory();
230 reg = reg->next();
231 }
232 }
233 fCurrIndex = 0;
reed@android.com161b00b2009-11-03 15:33:14 +0000234 if (SHOW_OVERVIEW) {
235 this->loadView(NULL);
236 } else {
237 this->loadView(fSamples[fCurrIndex]());
238 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239}
240
241SampleWindow::~SampleWindow() {
242 delete fPicture;
243 delete fGLCanvas;
244}
245
246void SampleWindow::onDraw(SkCanvas* canvas) {
247 if (fRepeatDrawing) {
248 this->inval(NULL);
249 }
250}
251
252#include "SkColorPriv.h"
253
254static void reverseRedAndBlue(const SkBitmap& bm) {
255 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
256 uint8_t* p = (uint8_t*)bm.getPixels();
257 uint8_t* stop = p + bm.getSize();
258 while (p < stop) {
259 // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
260 unsigned scale = SkAlpha255To256(p[3]);
261 unsigned r = p[2];
262 unsigned b = p[0];
263 p[0] = SkAlphaMul(r, scale);
264 p[1] = SkAlphaMul(p[1], scale);
265 p[2] = SkAlphaMul(b, scale);
266 p += 4;
267 }
268}
269
270SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
reed@android.com6efdc472008-12-19 18:24:35 +0000271#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000272#ifndef USE_OFFSCREEN
273 aglSetWindowRef(gAGLContext, NULL);
274#endif
reed@android.com6efdc472008-12-19 18:24:35 +0000275#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000276 switch (fCanvasType) {
277 case kRaster_CanvasType:
278 canvas = this->INHERITED::beforeChildren(canvas);
279 break;
280 case kPicture_CanvasType:
281 fPicture = new SkPicture;
282 canvas = fPicture->beginRecording(9999, 9999);
283 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000284#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000285 case kOpenGL_CanvasType: {
286 //SkGLCanvas::DeleteAllTextures(); // just for testing
287 SkDevice* device = canvas->getDevice();
288 const SkBitmap& bitmap = device->accessBitmap(true);
289 // first clear the raster bitmap, so we don't see any leftover bits
290 bitmap.eraseColor(0);
291 // now setup our glcanvas
292 setup_offscreen_gl(bitmap, (WindowRef)this->getHWND());
293 fGLCanvas = new SkGLCanvas;
294 fGLCanvas->setViewport(bitmap.width(), bitmap.height());
295 canvas = fGLCanvas;
296 break;
297 }
reed@android.com6efdc472008-12-19 18:24:35 +0000298#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000299 }
300
301 if (fUseClip) {
302 canvas->drawColor(0xFFFF88FF);
303 canvas->clipPath(fClipPath);
304 }
305
306 return canvas;
307}
308
309static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
310 const SkRegion& rgn) {
311 SkCanvas canvas(bm);
312 SkRegion inval(rgn);
313
314 inval.translate(r.fLeft, r.fTop);
315 canvas.clipRegion(inval);
316 canvas.drawColor(0xFFFF8080);
317}
318
319void SampleWindow::afterChildren(SkCanvas* orig) {
320 switch (fCanvasType) {
321 case kRaster_CanvasType:
322 break;
323 case kPicture_CanvasType:
reed@android.comaefd2bc2009-03-30 21:02:14 +0000324 if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000325 SkPicture* pict = new SkPicture(*fPicture);
326 fPicture->unref();
327 orig->drawPicture(*pict);
328 pict->unref();
reed@android.comaefd2bc2009-03-30 21:02:14 +0000329 } else if (true) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000330 SkDynamicMemoryWStream ostream;
331 fPicture->serialize(&ostream);
332 fPicture->unref();
333
334 SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
335 SkPicture pict(&istream);
336 orig->drawPicture(pict);
337 } else {
338 fPicture->draw(orig);
339 fPicture->unref();
340 }
341 fPicture = NULL;
342 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000343#ifdef SK_SUPPORT_GL
reed@android.com8a1c16f2008-12-17 15:59:43 +0000344 case kOpenGL_CanvasType:
345 glFlush();
346 delete fGLCanvas;
347 fGLCanvas = NULL;
348#ifdef USE_OFFSCREEN
349 reverseRedAndBlue(orig->getDevice()->accessBitmap(true));
350#endif
351 break;
reed@android.com6efdc472008-12-19 18:24:35 +0000352#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000353 }
354
355// if ((fScrollTestX | fScrollTestY) != 0)
356 {
357 const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
358 int dx = fScrollTestX * 7;
359 int dy = fScrollTestY * 7;
360 SkIRect r;
361 SkRegion inval;
362
363 r.set(50, 50, 50+100, 50+100);
364 bm.scrollRect(&r, dx, dy, &inval);
365 paint_rgn(bm, r, inval);
366 }
367}
368
reed@android.com6c5f6f22009-08-14 16:08:38 +0000369void SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
370 if (fScale) {
371 SkScalar scale = SK_Scalar1 * 7 / 10;
372 SkScalar cx = this->width() / 2;
373 SkScalar cy = this->height() / 2;
374 canvas->translate(cx, cy);
375 canvas->scale(scale, scale);
376 canvas->translate(-cx, -cy);
377 }
378 if (fRotate) {
379 SkScalar cx = this->width() / 2;
380 SkScalar cy = this->height() / 2;
381 canvas->translate(cx, cy);
382 canvas->rotate(SkIntToScalar(30));
383 canvas->translate(-cx, -cy);
384 }
385}
386
387void SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
388}
389
reed@android.com8a1c16f2008-12-17 15:59:43 +0000390static SkBitmap::Config gConfigCycle[] = {
391 SkBitmap::kNo_Config, // none -> none
392 SkBitmap::kNo_Config, // a1 -> none
393 SkBitmap::kNo_Config, // a8 -> none
394 SkBitmap::kNo_Config, // index8 -> none
395 SkBitmap::kARGB_4444_Config, // 565 -> 4444
396 SkBitmap::kARGB_8888_Config, // 4444 -> 8888
397 SkBitmap::kRGB_565_Config // 8888 -> 565
398};
399
400static SkBitmap::Config cycle_configs(SkBitmap::Config c) {
401 return gConfigCycle[c];
402}
403
404bool SampleWindow::nextSample() {
reed@android.com34245c72009-11-03 04:00:48 +0000405 fCurrIndex = (fCurrIndex + 1) % fSamples.count();
406 this->loadView(fSamples[fCurrIndex]());
407 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000408}
409
410bool SampleWindow::onEvent(const SkEvent& evt) {
411 if (evt.isType(ANIMATING_EVENTTYPE)) {
412 if (fAnimating) {
413 this->nextSample();
414 this->postAnimatingEvent();
415 }
416 return true;
417 }
reed@android.com34245c72009-11-03 04:00:48 +0000418 if (evt.isType("set-curr-index")) {
419 fCurrIndex = evt.getFast32() % fSamples.count();
420 this->loadView(fSamples[fCurrIndex]());
421 return true;
422 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000423 return this->INHERITED::onEvent(evt);
424}
425
reed@android.com0ae6b242008-12-23 16:49:54 +0000426static void cleanup_for_filename(SkString* name) {
427 char* str = name->writable_str();
428 for (int i = 0; i < name->size(); i++) {
429 switch (str[i]) {
430 case ':': str[i] = '-'; break;
431 case '/': str[i] = '-'; break;
432 case ' ': str[i] = '_'; break;
433 default: break;
434 }
435 }
436}
reed@android.com8a1c16f2008-12-17 15:59:43 +0000437
438bool SampleWindow::onHandleChar(SkUnichar uni) {
439 int dx = 0xFF;
440 int dy = 0xFF;
441
442 switch (uni) {
443 case '5': dx = 0; dy = 0; break;
444 case '8': dx = 0; dy = -1; break;
445 case '6': dx = 1; dy = 0; break;
446 case '2': dx = 0; dy = 1; break;
447 case '4': dx = -1; dy = 0; break;
448 case '7': dx = -1; dy = -1; break;
449 case '9': dx = 1; dy = -1; break;
450 case '3': dx = 1; dy = 1; break;
451 case '1': dx = -1; dy = 1; break;
452
453 default:
454 break;
455 }
456
457 if (0xFF != dx && 0xFF != dy) {
458 if ((dx | dy) == 0) {
459 fScrollTestX = fScrollTestY = 0;
460 } else {
461 fScrollTestX += dx;
462 fScrollTestY += dy;
463 }
464 this->inval(NULL);
465 return true;
466 }
467
reed@android.com0ae6b242008-12-23 16:49:54 +0000468 switch (uni) {
469 case 'a':
470 fAnimating = !fAnimating;
471 this->postAnimatingEvent();
472 this->updateTitle();
473 return true;
474 case 'f': {
475 const char* title = this->getTitle();
476 if (title[0] == 0) {
477 title = "sampleapp";
478 }
479 SkString name(title);
480 cleanup_for_filename(&name);
481 name.append(".png");
482 if (SkImageEncoder::EncodeFile(name.c_str(), this->getBitmap(),
reed@android.comb08eb2b2009-01-06 20:16:26 +0000483 SkImageEncoder::kPNG_Type, 100)) {
reed@android.com0ae6b242008-12-23 16:49:54 +0000484 SkDebugf("Created %s\n", name.c_str());
485 }
486 return true;
487 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000488 case 'r':
489 fRotate = !fRotate;
490 this->inval(NULL);
491 this->updateTitle();
492 return true;
493 case 's':
494 fScale = !fScale;
495 this->inval(NULL);
496 this->updateTitle();
497 return true;
reed@android.com0ae6b242008-12-23 16:49:54 +0000498 default:
499 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000500 }
501
502 return this->INHERITED::onHandleChar(uni);
503}
504
505#include "SkDumpCanvas.h"
506
507bool SampleWindow::onHandleKey(SkKey key) {
508 switch (key) {
509 case kRight_SkKey:
510 if (this->nextSample()) {
511 return true;
512 }
513 break;
514 case kLeft_SkKey:
515 fCanvasType = cycle_canvastype(fCanvasType);
516 this->updateTitle();
517 this->inval(NULL);
518 return true;
519 case kUp_SkKey:
520 fUseClip = !fUseClip;
521 this->updateTitle();
522 this->inval(NULL);
523 return true;
524 case kDown_SkKey:
525 this->setConfig(cycle_configs(this->getBitmap().config()));
526 this->updateTitle();
527 return true;
528 case kOK_SkKey:
529 if (true) {
530 SkDebugfDumper dumper;
531 SkDumpCanvas dc(&dumper);
532 this->draw(&dc);
533 } else {
534 fRepeatDrawing = !fRepeatDrawing;
535 if (fRepeatDrawing) {
536 this->inval(NULL);
537 }
538 }
539 return true;
reed@android.com34245c72009-11-03 04:00:48 +0000540 case kBack_SkKey:
541 this->loadView(NULL);
542 return true;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000543 default:
544 break;
545 }
546 return this->INHERITED::onHandleKey(key);
547}
548
549void SampleWindow::loadView(SkView* view) {
550 SkView::F2BIter iter(this);
551 SkView* prev = iter.next();
552 if (prev) {
553 prev->detachFromParent();
554 }
reed@android.com34245c72009-11-03 04:00:48 +0000555
556 if (NULL == view) {
557 view = create_overview(fSamples.count(), fSamples.begin());
558 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000559 view->setVisibleP(true);
560 this->attachChildToFront(view)->unref();
561 view->setSize(this->width(), this->height());
562
563 this->updateTitle();
564}
565
566static const char* gConfigNames[] = {
567 "unknown config",
568 "A1",
569 "A8",
570 "Index8",
571 "565",
572 "4444",
573 "8888"
574};
575
576static const char* configToString(SkBitmap::Config c) {
577 return gConfigNames[c];
578}
579
580static const char* gCanvasTypePrefix[] = {
581 "raster: ",
582 "picture: ",
583 "opengl: "
584};
585
586void SampleWindow::updateTitle() {
587 SkString title;
588
589 SkView::F2BIter iter(this);
590 SkView* view = iter.next();
591 SkEvent evt(gTitleEvtName);
592 if (view->doQuery(&evt)) {
593 title.set(evt.findString(gTitleEvtName));
594 }
595 if (title.size() == 0) {
596 title.set("<unknown>");
597 }
598
599 title.prepend(gCanvasTypePrefix[fCanvasType]);
600
601 title.prepend(" ");
602 title.prepend(configToString(this->getBitmap().config()));
603
604 if (fAnimating) {
605 title.prepend("<A> ");
606 }
reed@android.com6c5f6f22009-08-14 16:08:38 +0000607 if (fScale) {
608 title.prepend("<S> ");
609 }
610 if (fRotate) {
611 title.prepend("<R> ");
612 }
613
reed@android.com8a1c16f2008-12-17 15:59:43 +0000614 this->setTitle(title.c_str());
615}
616
617void SampleWindow::onSizeChange() {
618 this->INHERITED::onSizeChange();
619
620 SkView::F2BIter iter(this);
621 SkView* view = iter.next();
622 view->setSize(this->width(), this->height());
623
624 // rebuild our clippath
625 {
626 const SkScalar W = this->width();
627 const SkScalar H = this->height();
628
629 fClipPath.reset();
630#if 0
631 for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
632 SkRect r;
633 r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
634 for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
635 fClipPath.addRect(r);
636 }
637#else
638 SkRect r;
639 r.set(0, 0, W, H);
640 fClipPath.addRect(r, SkPath::kCCW_Direction);
641 r.set(W/4, H/4, W*3/4, H*3/4);
642 fClipPath.addRect(r, SkPath::kCW_Direction);
643#endif
644 }
645
646 this->updateTitle(); // to refresh our config
647}
648
649///////////////////////////////////////////////////////////////////////////////
650
651SkOSWindow* create_sk_window(void* hwnd) {
652 return new SampleWindow(hwnd);
653}
654
655void get_preferred_size(int* x, int* y, int* width, int* height) {
656 *x = 10;
657 *y = 50;
658 *width = 640;
659 *height = 480;
660}
661
662void application_init() {
663// setenv("ANDROID_ROOT", "../../../data", 0);
664 setenv("ANDROID_ROOT", "/android/device/data", 0);
reed@android.com5e5adfd2009-03-07 03:39:23 +0000665 SkGraphics::Init();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000666 SkEvent::Init();
667}
668
669void application_term() {
670 SkEvent::Term();
671 SkGraphics::Term();
672}