SampleApp.cpp revision 06c3b6bfd53c93d5ba49cf4d87b2c5c1bf33f072
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDevice.h"
3ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "SkGpuCanvas.h"
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
5b08eb2b3bce45411494fe00258e4c91248ccd15ereed@android.com#include "SkImageEncoder.h"
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h"
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
94417740a480786ca65379ba5b398c500ba34ee18reed@android.com#include "SkTime.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkWindow.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrContext.h"
14f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
15f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com//#define DEFAULT_TO_GPU
16f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
17e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.comextern SkView* create_overview(int, const SkViewFactory[]);
1834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com
19cb34235f46b6259b612e72c416e850e26803250areed@android.com#define SK_SUPPORT_GL
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ANIMATING_EVENTTYPE "nextSample"
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ANIMATING_DELAY     750
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#ifdef SK_SUPPORT_GL
25ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    #include "GrGLConfig.h"
26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkViewRegister* SkViewRegister::gHead;
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool gOnce;
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gHead = NULL;
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
352e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fChain = gHead;
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    gHead = this;
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
40f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#if defined(SK_SUPPORT_GL)
41f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    #define SK_USE_SHADERS
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4406c3b6bfd53c93d5ba49cf4d87b2c5c1bf33f072twiz@google.com#ifdef SK_BUILD_FOR_MAC
45f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#include <CoreFoundation/CoreFoundation.h>
46f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#include <CoreFoundation/CFURLAccess.h>
47f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
48f0b5f68807cfa18cce0647d275778147901945cdreed@google.comstatic void testpdf() {
49f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
50f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                                 kCFStringEncodingUTF8);
51f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
52f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                              kCFURLPOSIXPathStyle,
53f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                              false);
54f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFRelease(path);
55f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGRect box = CGRectMake(0, 0, 8*72, 10*72);
56f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
57f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFRelease(url);
58f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
59f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextBeginPage(cg, &box);
60f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
61f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextFillEllipseInRect(cg, r);
62f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextEndPage(cg);
63f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextRelease(cg);
64f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
65f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    if (false) {
66f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        SkBitmap bm;
67f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        bm.setConfig(SkBitmap::kA8_Config, 64, 64);
68f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        bm.allocPixels();
69f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        bm.eraseColor(0);
70f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
71f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        SkCanvas canvas(bm);
72f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
73f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
74f0b5f68807cfa18cce0647d275778147901945cdreed@google.com}
75f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#endif
76f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
77f0b5f68807cfa18cce0647d275778147901945cdreed@google.com//////////////////////////////////////////////////////////////////////////////
78f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
79f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#include "SkDrawFilter.h"
80f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
81f0b5f68807cfa18cce0647d275778147901945cdreed@google.comclass LCDTextDrawFilter : public SkDrawFilter {
82f0b5f68807cfa18cce0647d275778147901945cdreed@google.compublic:
83f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    enum Mode {
84f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        kNeutral_Mode,
85f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        kForceOn_Mode,
86f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        kForceOff_Mode
87f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    };
88f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
89f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    LCDTextDrawFilter(Mode mode) : fMode(mode) {}
90f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
91f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    virtual bool filter(SkCanvas*, SkPaint* paint, Type t) {
92f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        if (kText_Type == t && kNeutral_Mode != fMode) {
93f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            fPrevLCD = paint->isLCDRenderText();
94f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            paint->setLCDRenderText(kForceOn_Mode == fMode);
95f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        }
96f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        return true;
97f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
98f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
99f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    /** If filter() returned true, then restore() will be called to restore the
100f0b5f68807cfa18cce0647d275778147901945cdreed@google.com     canvas/paint to their previous states
101f0b5f68807cfa18cce0647d275778147901945cdreed@google.com     */
102f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    virtual void restore(SkCanvas*, SkPaint* paint, Type t) {
103f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        if (kText_Type == t && kNeutral_Mode != fMode) {
104f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            paint->setLCDRenderText(fPrevLCD);
105f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        }
106f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
107f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
108f0b5f68807cfa18cce0647d275778147901945cdreed@google.comprivate:
109f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    Mode    fMode;
110f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    bool    fPrevLCD;
111f0b5f68807cfa18cce0647d275778147901945cdreed@google.com};
112f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
113f0b5f68807cfa18cce0647d275778147901945cdreed@google.comLCDTextDrawFilter::Mode cycle_lcdmode(LCDTextDrawFilter::Mode mode) {
114f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    static const LCDTextDrawFilter::Mode gCycle[] = {
115f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        /* kNeutral_Mode  -> */  LCDTextDrawFilter::kForceOn_Mode,
116f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        /* kForceOn_Mode  -> */  LCDTextDrawFilter::kForceOff_Mode,
117f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        /* kForceOff_Mode -> */  LCDTextDrawFilter::kNeutral_Mode
118f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    };
119f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    return gCycle[mode];
120f0b5f68807cfa18cce0647d275778147901945cdreed@google.com}
121f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
124f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gCharEvtName[] = "SampleCode_Char_Event";
125f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gKeyEvtName[] = "SampleCode_Key_Event";
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gTitleEvtName[] = "SampleCode_Title_Event";
1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
128f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gFastTextEvtName[] = "SampleCode_FastText_Event";
129f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
130f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
131f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
132f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outUni) {
133f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outUni = evt.getFast32();
134f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
135f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
136f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
137f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
138f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
139f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
140f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
141f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
142f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outKey) {
143f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outKey = (SkKey)evt.getFast32();
144f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
145f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
146f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
147f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
148f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::TitleQ(const SkEvent& evt) {
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::TitleR(SkEvent* evt, const char title[]) {
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && TitleQ(*evt));
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setString(gTitleEvtName, title);
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::PrefSizeQ(const SkEvent& evt) {
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && PrefSizeQ(*evt));
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar size[2];
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[0] = width;
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[1] = height;
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setScalars(gPrefSizeEvtName, 2, size);
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
171f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::FastTextQ(const SkEvent& evt) {
172f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
173f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
174f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com///////////////////////////////////////////////////////////////////////////////
176f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1774417740a480786ca65379ba5b398c500ba34ee18reed@android.comstatic SkMSec gAnimTime;
178f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkMSec gAnimTimePrev;
179f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1804417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkMSec SampleCode::GetAnimTime() { return gAnimTime; }
181f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
182f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkScalar SampleCode::GetAnimSecondsDelta() {
183f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
184f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
1854417740a480786ca65379ba5b398c500ba34ee18reed@android.com
1864417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
187f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // since gAnimTime can be up to 32 bits, we can't convert it to a float
188f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // or we'll lose the low bits. Hence we use doubles for the intermediate
189f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // calculations
190f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double seconds = (double)gAnimTime / 1000.0;
191f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double value = SkScalarToDouble(speed) * seconds;
1924417740a480786ca65379ba5b398c500ba34ee18reed@android.com    if (period) {
193f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        value = ::fmod(value, SkScalarToDouble(period));
1944417740a480786ca65379ba5b398c500ba34ee18reed@android.com    }
195f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(value);
1964417740a480786ca65379ba5b398c500ba34ee18reed@android.com}
1974417740a480786ca65379ba5b398c500ba34ee18reed@android.com
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
200f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkView* curr_view(SkWindow* wind) {
201f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkView::F2BIter iter(wind);
202f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return iter.next();
203f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
204f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SampleWindow : public SkOSWindow {
20634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    SkTDArray<SkViewFactory> fSamples;
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
2082fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SampleWindow(void* hwnd);
2092fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual ~SampleWindow();
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
211e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    virtual void draw(SkCanvas* canvas);
212e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void onDraw(SkCanvas* canvas);
2152fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool onHandleKey(SkKey key);
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual bool onHandleChar(SkUnichar);
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void onSizeChange();
2182e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual SkCanvas* beforeChildren(SkCanvas*);
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void afterChildren(SkCanvas*);
2216c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    virtual void beforeChild(SkView* child, SkCanvas* canvas);
2226c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    virtual void afterChild(SkView* child, SkCanvas* canvas);
2232e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2242fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool onEvent(const SkEvent& evt);
225f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    virtual bool onQuery(SkEvent* evt);
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0
2282fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool handleChar(SkUnichar uni);
2292fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool handleEvent(const SkEvent& evt);
2302fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool handleKey(SkKey key);
2312fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool handleKeyUp(SkKey key);
2322e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2332fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual bool onClick(Click* click);
2342fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual bool onHandleKeyUp(SkKey key);
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2372e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
23934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    int fCurrIndex;
2402e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPicture* fPicture;
242f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkGpuCanvas* fGpuCanvas;
2432e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    GrContext* fGrContext;
2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath fClipPath;
2452e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum CanvasType {
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kRaster_CanvasType,
2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kPicture_CanvasType,
249f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        kGPU_CanvasType
2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    CanvasType fCanvasType;
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool fUseClip;
254e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    bool fNClip;
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool fRepeatDrawing;
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool fAnimating;
2576c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    bool fRotate;
2586c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    bool fScale;
259f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    bool fRequestGrabImage;
2602e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
261f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    LCDTextDrawFilter::Mode fLCDMode;
262f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int fScrollTestX, fScrollTestY;
2642e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2652e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    bool make3DReady();
2662e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void loadView(SkView*);
2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void updateTitle();
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool nextSample();
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void postAnimatingEvent() {
2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fAnimating) {
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            evt->post(this->getSinkID(), ANIMATING_DELAY);
2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2772e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2782e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static CanvasType cycle_canvastype(CanvasType);
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    typedef SkOSWindow INHERITED;
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2842e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.combool SampleWindow::make3DReady() {
2852e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2862e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com#if defined(SK_SUPPORT_GL)
287498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com    if (attachGL()) {
288498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        if (NULL == fGrContext) {
289498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        #if defined(SK_USE_SHADERS)
290498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com            fGrContext = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
291498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        #else
292498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com            fGrContext = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
293498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        #endif
294498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        }
2952e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
296498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        if (NULL != fGrContext) {
297498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com            return true;
298498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        } else {
299498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com            detachGL();
300498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        }
3012e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    }
3022e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com#endif
3032e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    SkDebugf("Failed to setup 3D");
3042e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    return false;
3052e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com}
3062e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static const CanvasType gCT[] = {
3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kPicture_CanvasType,
310f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        kGPU_CanvasType,
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kRaster_CanvasType
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gCT[ct];
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPicture = NULL;
318f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    fGpuCanvas = NULL;
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3202e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    fGrContext = NULL;
3212e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#ifdef DEFAULT_TO_GPU
323f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    fCanvasType = kGPU_CanvasType;
324f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#else
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fCanvasType = kRaster_CanvasType;
326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#endif
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fUseClip = false;
328e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    fNClip = false;
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fRepeatDrawing = false;
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fAnimating = false;
3316c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    fRotate = false;
3326c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    fScale = false;
333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    fRequestGrabImage = false;
334f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    fLCDMode = LCDTextDrawFilter::kNeutral_Mode;
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fScrollTestX = fScrollTestY = 0;
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3372fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com//    this->setConfig(SkBitmap::kRGB_565_Config);
3382fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    this->setConfig(SkBitmap::kARGB_8888_Config);
3392fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    this->setVisibleP(true);
340f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    this->setClipToBounds(false);
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
34234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    {
34334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        const SkViewRegister* reg = SkViewRegister::Head();
34434245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        while (reg) {
34534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            *fSamples.append() = reg->factory();
34634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            reg = reg->next();
34734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        }
34834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    }
34934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    fCurrIndex = 0;
350e0f13eeb8e527cfd2541063ba2dd89c7d31d71cereed@android.com    this->loadView(fSamples[fCurrIndex]());
351f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
35206c3b6bfd53c93d5ba49cf4d87b2c5c1bf33f072twiz@google.com#ifdef SK_BUILD_FOR_MAC
353f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    testpdf();
35406c3b6bfd53c93d5ba49cf4d87b2c5c1bf33f072twiz@google.com#endif
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSampleWindow::~SampleWindow() {
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    delete fPicture;
359f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    delete fGpuCanvas;
3602e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    if (NULL != fGrContext) {
3612e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com        fGrContext->unref();
3622e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com    }
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
36555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic SkBitmap capture_bitmap(SkCanvas* canvas) {
36655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkBitmap bm;
36755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
36855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    src.copyTo(&bm, src.config());
36955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return bm;
37055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
37155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
37255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
37355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                        SkBitmap* diff) {
37455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
3752e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
37655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp0(src);
37755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp1(orig);
37855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    for (int y = 0; y < src.height(); y++) {
37955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* srcP = src.getAddr(0, y);
38055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* origP = orig.getAddr(0, y);
38155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        size_t bytes = src.width() * src.bytesPerPixel();
38255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (memcmp(srcP, origP, bytes)) {
38355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkDebugf("---------- difference on line %d\n", y);
38455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            return true;
38555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
38655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    }
38755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return false;
38855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
38955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
3904417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define XCLIP_N  8
3914417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define YCLIP_N  8
392e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
393e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.comvoid SampleWindow::draw(SkCanvas* canvas) {
3944417740a480786ca65379ba5b398c500ba34ee18reed@android.com    // update the animation time
395f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    gAnimTimePrev = gAnimTime;
3964417740a480786ca65379ba5b398c500ba34ee18reed@android.com    gAnimTime = SkTime::GetMSecs();
3974417740a480786ca65379ba5b398c500ba34ee18reed@android.com
398e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
39955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        this->INHERITED::draw(canvas);
40055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap orig = capture_bitmap(canvas);
401e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
402e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar w = this->width();
403e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar h = this->height();
404e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar cw = w / XCLIP_N;
405e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar ch = h / YCLIP_N;
406e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        for (int y = 0; y < YCLIP_N; y++) {
40755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkRect r;
40855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fTop = y * ch;
40955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fBottom = (y + 1) * ch;
41055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            if (y == YCLIP_N - 1) {
41155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fBottom = h;
41255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            }
413e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            for (int x = 0; x < XCLIP_N; x++) {
414e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                SkAutoCanvasRestore acr(canvas, true);
41555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fLeft = x * cw;
41655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fRight = (x + 1) * cw;
41755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                if (x == XCLIP_N - 1) {
41855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                    r.fRight = w;
41955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                }
420e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                canvas->clipRect(r);
421e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                this->INHERITED::draw(canvas);
422e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            }
423e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        }
4242e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
42555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap diff;
42655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (bitmap_diff(canvas, orig, &diff)) {
42755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
428e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    } else {
429e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        this->INHERITED::draw(canvas);
430e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
431e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com}
432e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onDraw(SkCanvas* canvas) {
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fRepeatDrawing) {
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void reverseRedAndBlue(const SkBitmap& bm) {
4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* p = (uint8_t*)bm.getPixels();
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* stop = p + bm.getSize();
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (p < stop) {
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = SkAlpha255To256(p[3]);
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned r = p[2];
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned b = p[0];
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[0] = SkAlphaMul(r, scale);
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[1] = SkAlphaMul(p[1], scale);
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[2] = SkAlphaMul(b, scale);
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p += 4;
4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
458f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkIPoint viewport;
459f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    bool alreadyGPU = canvas->getViewport(&viewport);
4602e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
461f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (kGPU_CanvasType != fCanvasType) {
4626efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#ifdef SK_SUPPORT_GL
463f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        detachGL();
4642e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com#endif
465f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
4662e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (fCanvasType) {
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kRaster_CanvasType:
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas = this->INHERITED::beforeChildren(canvas);
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kPicture_CanvasType:
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fPicture = new SkPicture;
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            canvas = fPicture->beginRecording(9999, 9999);
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
475ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        case kGPU_CanvasType: {
4762e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com            if (!alreadyGPU && make3DReady()) {
477f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                SkDevice* device = canvas->getDevice();
4782e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com                const SkBitmap& bitmap = device->accessBitmap(true);
4792e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
4805782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                GrRenderTarget* renderTarget;
4815782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                renderTarget = fGrContext->createRenderTargetFrom3DApiState();
4825782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                fGpuCanvas = new SkGpuCanvas(fGrContext, renderTarget);
4835782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                renderTarget->unref();
4845782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
4852fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com                device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
4862fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com                                                  bitmap.width(), bitmap.height(),
4872fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com                                                  false, false);
488ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                fGpuCanvas->setDevice(device)->unref();
489f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                canvas = fGpuCanvas;
4902e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
491f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            } else {
492f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                canvas = this->INHERITED::beforeChildren(canvas);
493f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
495ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fUseClip) {
4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawColor(0xFFFF88FF);
5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->clipPath(fClipPath);
5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return canvas;
5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void paint_rgn(const SkBitmap& bm, const SkIRect& r,
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                      const SkRegion& rgn) {
5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkCanvas    canvas(bm);
5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRegion    inval(rgn);
5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inval.translate(r.fLeft, r.fTop);
5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.clipRegion(inval);
5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.drawColor(0xFFFF8080);
5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::afterChildren(SkCanvas* orig) {
517f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (fRequestGrabImage) {
518f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        fRequestGrabImage = false;
5192e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
520f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig;
521f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDevice* device = canvas->getDevice();
522f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkBitmap bitmap;
5235ba2d5b187021beafb2c8aebe6bf4ae4cde67ae4reed@google.com        SkIRect bounds = {
5245ba2d5b187021beafb2c8aebe6bf4ae4cde67ae4reed@google.com            0, 0,
5255ba2d5b187021beafb2c8aebe6bf4ae4cde67ae4reed@google.com            SkScalarRound(this->width()),
5265ba2d5b187021beafb2c8aebe6bf4ae4cde67ae4reed@google.com            SkScalarRound(this->height())
5275ba2d5b187021beafb2c8aebe6bf4ae4cde67ae4reed@google.com        };
528f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (device->readPixels(bounds, &bitmap)) {
529f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            static int gSampleGrabCounter;
530f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkString name;
531f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            name.printf("sample_grab_%d", gSampleGrabCounter++);
532f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkImageEncoder::EncodeFile(name.c_str(), bitmap,
533f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                                       SkImageEncoder::kPNG_Type, 100);
534f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
535f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
536f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (fCanvasType) {
5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kRaster_CanvasType:
5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kPicture_CanvasType:
541aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com            if (true) {
5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkPicture* pict = new SkPicture(*fPicture);
5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPicture->unref();
5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                orig->drawPicture(*pict);
5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                pict->unref();
546aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com            } else if (true) {
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkDynamicMemoryWStream ostream;
5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPicture->serialize(&ostream);
5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPicture->unref();
5502e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkPicture pict(&istream);
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                orig->drawPicture(pict);
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPicture->draw(orig);
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fPicture->unref();
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fPicture = NULL;
5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
5606efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#ifdef SK_SUPPORT_GL
561f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        case kGPU_CanvasType:
562f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            delete fGpuCanvas;
563f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            fGpuCanvas = NULL;
564f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            presentGL();
565f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
5666efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#endif
5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5682e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    if ((fScrollTestX | fScrollTestY) != 0)
570f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (false) {
5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dx = fScrollTestX * 7;
5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dy = fScrollTestY * 7;
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIRect r;
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRegion inval;
5762e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(50, 50, 50+100, 50+100);
5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bm.scrollRect(&r, dx, dy, &inval);
5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint_rgn(bm, r, inval);
5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5836c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
5846c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fScale) {
5856c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar scale = SK_Scalar1 * 7 / 10;
5866c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cx = this->width() / 2;
5876c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cy = this->height() / 2;
5886c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(cx, cy);
5896c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->scale(scale, scale);
5906c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(-cx, -cy);
5916c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
5926c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
5936c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cx = this->width() / 2;
5946c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cy = this->height() / 2;
5956c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(cx, cy);
5966c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->rotate(SkIntToScalar(30));
5976c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(-cx, -cy);
5986c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
599f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
600f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    if (LCDTextDrawFilter::kNeutral_Mode != fLCDMode) {
601f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        canvas->setDrawFilter(new LCDTextDrawFilter(fLCDMode))->unref();
602f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
6036c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
6046c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
6056c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
606f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    canvas->setDrawFilter(NULL);
6076c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
6086c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkBitmap::Config gConfigCycle[] = {
6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // none -> none
6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // a1 -> none
6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // a8 -> none
6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // index8 -> none
6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kARGB_4444_Config,    // 565 -> 4444
6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kARGB_8888_Config,    // 4444 -> 8888
6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kRGB_565_Config       // 8888 -> 565
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkBitmap::Config cycle_configs(SkBitmap::Config c) {
6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gConfigCycle[c];
6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::nextSample() {
62434245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    fCurrIndex = (fCurrIndex + 1) % fSamples.count();
62534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    this->loadView(fSamples[fCurrIndex]());
62634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    return true;
6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onEvent(const SkEvent& evt) {
6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (evt.isType(ANIMATING_EVENTTYPE)) {
6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fAnimating) {
6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->nextSample();
6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->postAnimatingEvent();
6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
63734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    if (evt.isType("set-curr-index")) {
63834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        fCurrIndex = evt.getFast32() % fSamples.count();
63934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        this->loadView(fSamples[fCurrIndex]());
64034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        return true;
64134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    }
6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onEvent(evt);
6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
645f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleWindow::onQuery(SkEvent* query) {
646f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-count")) {
647f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        query->setFast32(fSamples.count());
648f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
649f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
650f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-title")) {
651f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = fSamples[query->getFast32()]();
652f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gTitleEvtName);
653f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->doQuery(&evt)) {
654f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            query->setString("title", evt.findString(gTitleEvtName));
655f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
656f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkSafeUnref(view);
657f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
658f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
659f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("use-fast-text")) {
660f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gFastTextEvtName);
661f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return curr_view(this)->doQuery(&evt);
662f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
663f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return this->INHERITED::onQuery(query);
664f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
665f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
6660ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.comstatic void cleanup_for_filename(SkString* name) {
6670ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    char* str = name->writable_str();
668e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com    for (size_t i = 0; i < name->size(); i++) {
6690ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        switch (str[i]) {
6700ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ':': str[i] = '-'; break;
6710ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case '/': str[i] = '-'; break;
6720ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ' ': str[i] = '_'; break;
6730ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            default: break;
6740ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        }
6750ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    }
6760ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com}
6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleChar(SkUnichar uni) {
679f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
680f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
681f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
682f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gCharEvtName);
683f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(uni);
684f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
685f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
686f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
687f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
688f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
6892e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dx = 0xFF;
6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dy = 0xFF;
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (uni) {
6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '5': dx =  0; dy =  0; break;
6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '8': dx =  0; dy = -1; break;
6968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '6': dx =  1; dy =  0; break;
6978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '2': dx =  0; dy =  1; break;
6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '4': dx = -1; dy =  0; break;
6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '7': dx = -1; dy = -1; break;
7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '9': dx =  1; dy = -1; break;
7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '3': dx =  1; dy =  1; break;
7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '1': dx = -1; dy =  1; break;
7032e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
7072e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0xFF != dx && 0xFF != dy) {
7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((dx | dy) == 0) {
7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX = fScrollTestY = 0;
7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX += dx;
7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestY += dy;
7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
7182e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
7190ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    switch (uni) {
7200ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        case 'a':
7210ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            fAnimating = !fAnimating;
7220ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            this->postAnimatingEvent();
7230ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            this->updateTitle();
7240ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            return true;
7250ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        case 'f': {
7260ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            const char* title = this->getTitle();
7270ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            if (title[0] == 0) {
7280ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com                title = "sampleapp";
7290ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            }
7300ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            SkString name(title);
7310ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            cleanup_for_filename(&name);
7320ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            name.append(".png");
7330ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            if (SkImageEncoder::EncodeFile(name.c_str(), this->getBitmap(),
734b08eb2b3bce45411494fe00258e4c91248ccd15ereed@android.com                                           SkImageEncoder::kPNG_Type, 100)) {
7350ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com                SkDebugf("Created %s\n", name.c_str());
7360ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            }
7370ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            return true;
7380ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        }
7396c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        case 'r':
7406c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fRotate = !fRotate;
7416c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            this->inval(NULL);
7426c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            this->updateTitle();
7436c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            return true;
7446c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        case 's':
7456c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            fScale = !fScale;
7466c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            this->inval(NULL);
7476c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            this->updateTitle();
7486c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com            return true;
749fb56a9ee2d64e11aae6d225cb905e95e4a0ee6e5reed@google.com        case 'c':
750fb56a9ee2d64e11aae6d225cb905e95e4a0ee6e5reed@google.com            fUseClip = !fUseClip;
751fb56a9ee2d64e11aae6d225cb905e95e4a0ee6e5reed@google.com            this->inval(NULL);
752fb56a9ee2d64e11aae6d225cb905e95e4a0ee6e5reed@google.com            this->updateTitle();
753fb56a9ee2d64e11aae6d225cb905e95e4a0ee6e5reed@google.com            return true;
754f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        case 'd':
755f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkGraphics::SetFontCacheUsed(0);
756f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return true;
757f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        case 'g':
758f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            fRequestGrabImage = true;
759f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            this->inval(NULL);
760f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
761f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        case 'l':
762f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            fLCDMode = cycle_lcdmode(fLCDMode);
763f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            this->updateTitle();
764f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            this->inval(NULL);
765f0b5f68807cfa18cce0647d275778147901945cdreed@google.com            break;
7660ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        default:
7670ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            break;
7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
7692e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleChar(uni);
7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDumpCanvas.h"
7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleKey(SkKey key) {
776f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
777f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
778f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
779f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gKeyEvtName);
780f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(key);
781f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
782f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
783f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
784f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
785f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
786f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (key) {
7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kRight_SkKey:
7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (this->nextSample()) {
7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kLeft_SkKey:
7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fCanvasType = cycle_canvastype(fCanvasType);
7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->updateTitle();
7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->inval(NULL);
7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kUp_SkKey:
799e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            fNClip = !fNClip;
8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->updateTitle();
8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->inval(NULL);
8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kDown_SkKey:
8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->setConfig(cycle_configs(this->getBitmap().config()));
8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->updateTitle();
8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kOK_SkKey:
808f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (false) {
8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkDebugfDumper dumper;
8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkDumpCanvas dc(&dumper);
8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this->draw(&dc);
8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } else {
8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fRepeatDrawing = !fRepeatDrawing;
8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (fRepeatDrawing) {
8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    this->inval(NULL);
8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
81934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        case kBack_SkKey:
82034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            this->loadView(NULL);
82134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            return true;
8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleKey(key);
8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::loadView(SkView* view) {
8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* prev = iter.next();
8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (prev) {
8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        prev->detachFromParent();
8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8342e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
83534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    if (NULL == view) {
83634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        view = create_overview(fSamples.count(), fSamples.begin());
83734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    }
8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setVisibleP(true);
839f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    view->setClipToBounds(false);
8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->attachChildToFront(view)->unref();
8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();
8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* gConfigNames[] = {
8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "unknown config",
8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "A1",
8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "A8",
8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "Index8",
8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "565",
8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "4444",
8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "8888"
8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* configToString(SkBitmap::Config c) {
8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gConfigNames[c];
8588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* gCanvasTypePrefix[] = {
8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "raster: ",
8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "picture: ",
8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "opengl: "
8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::updateTitle() {
8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkString title;
8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* view = iter.next();
8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkEvent evt(gTitleEvtName);
8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (view->doQuery(&evt)) {
8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.set(evt.findString(gTitleEvtName));
8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (title.size() == 0) {
8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.set("<unknown>");
8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8782e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(gCanvasTypePrefix[fCanvasType]);
8808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(" ");
8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(configToString(this->getBitmap().config()));
8832e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fAnimating) {
8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.prepend("<A> ");
8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
8876c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fScale) {
8886c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        title.prepend("<S> ");
8896c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
8906c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
8916c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        title.prepend("<R> ");
8926c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
893e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
894e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        title.prepend("<C> ");
895e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
896f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    if (LCDTextDrawFilter::kForceOn_Mode == fLCDMode) {
897f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        title.prepend("LCD ");
898f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    } else if (LCDTextDrawFilter::kForceOff_Mode == fLCDMode) {
899f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        title.prepend("lcd ");
900f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->setTitle(title.c_str());
9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onSizeChange() {
9058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::onSizeChange();
9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* view = iter.next();
9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
9102e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // rebuild our clippath
9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
9138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar W = this->width();
9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar H = this->height();
9152e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.reset();
9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0
9188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
9198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkRect r;
9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fClipPath.addRect(r);
9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRect r;
9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(0, 0, W, H);
9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCCW_Direction);
9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(W/4, H/4, W*3/4, H*3/4);
9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCW_Direction);
9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
9322e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();    // to refresh our config
9348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
9358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
938f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comtemplate <typename T> void SkTBSort(T array[], int count) {
939f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 1; i < count - 1; i++) {
940f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        bool didSwap = false;
941f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = count - 1; j > i; --j) {
942f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (array[j] < array[j-1]) {
943f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                T tmp(array[j-1]);
944f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j-1] = array[j];
945f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j] = tmp;
946f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                didSwap = true;
947f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
948f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
949f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (!didSwap) {
950f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
951f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
952f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
9532e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
954f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int k = 0; k < count - 1; k++) {
955f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkASSERT(!(array[k+1] < array[k]));
956f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
957f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
958f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
959f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkRandom.h"
960f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
961f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void rand_rect(SkIRect* rect, SkRandom& rand) {
962f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int bits = 8;
963f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int shift = 32 - bits;
964f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
965f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com              rand.nextU() >> shift, rand.nextU() >> shift);
966f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->sort();
967f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
968f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
969f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void dumpRect(const SkIRect& r) {
970f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf(" { %d, %d, %d, %d },\n",
971f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fLeft, r.fTop,
972f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fRight, r.fBottom);
973f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
974f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
975f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test_rects(const SkIRect rect[], int count) {
976f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRegion rgn0, rgn1;
977f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
978f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 0; i < count; i++) {
979f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        rgn0.op(rect[i], SkRegion::kUnion_Op);
980f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com     //   dumpRect(rect[i]);
981f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
982f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rgn1.setRects(rect, count);
983f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
984f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (rgn0 != rgn1) {
985f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
986f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int i = 0; i < count; i++) {
987f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            dumpRect(rect[i]);
988f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
989f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
990f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
991f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
992f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
993f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test() {
994f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    size_t i;
995f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
996f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r0[] = {
997f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 1 },
998f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 2, 3, 3 },
999f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
1000f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r1[] = {
1001f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 3 },
1002f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 1, 1, 2, 2 },
1003f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 0, 3, 3 },
1004f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
1005f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r2[] = {
1006f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 2 },
1007f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 1, 3, 3 },
1008f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 4, 0, 5, 1 },
1009f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 6, 0, 7, 4 },
1010f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
1011f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1012f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const struct {
1013f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const SkIRect* fRects;
1014f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        int            fCount;
1015f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } gRecs[] = {
1016f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r0, SK_ARRAY_COUNT(r0) },
1017f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r1, SK_ARRAY_COUNT(r1) },
1018f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r2, SK_ARRAY_COUNT(r2) },
1019f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
1020f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1021f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
1022f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(gRecs[i].fRects, gRecs[i].fCount);
1023f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
10242e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
1025f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRandom rand;
1026f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < 10000; i++) {
1027f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkRegion rgn0, rgn1;
1028f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1029f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const int N = 8;
1030f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkIRect rect[N];
1031f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = 0; j < N; j++) {
1032f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rand_rect(&rect[j], rand);
1033f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1034f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(rect, N);
1035f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1036f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
1037f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkOSWindow* create_sk_window(void* hwnd) {
1039f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com//    test();
10402fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    return new SampleWindow(hwnd);
10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid get_preferred_size(int* x, int* y, int* width, int* height) {
10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *x = 10;
10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *y = 50;
10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *width = 640;
10478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *height = 480;
10488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_init() {
10518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    setenv("ANDROID_ROOT", "../../../data", 0);
1052e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#ifdef SK_BUILD_FOR_MAC
10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    setenv("ANDROID_ROOT", "/android/device/data", 0);
1054e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#endif
10552fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Init();
10562fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Init();
10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_term() {
10602fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Term();
10612fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Term();
10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1063