SampleApp.cpp revision fec0bc3fc13481f5bcb341ab2d2d695911f39bd4
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
72c8208f3a444098aee562f5a1ef620142807eda2Scroggo#include "SampleApp.h"
82c8208f3a444098aee562f5a1ef620142807eda2Scroggo
98a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkData.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDevice.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h"
13b08eb2b3bce45411494fe00258e4c91248ccd15ereed@android.com#include "SkImageEncoder.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPicture.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
174417740a480786ca65379ba5b398c500ba34ee18reed@android.com#include "SkTime.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkWindow.h"
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h"
210f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo#include "SkTypeface.h"
22f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
23cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
246bf38b59c9de1cd35cd091cf8766117f4e1f66a0tomhudson@google.com#include "gl/GrGLInterface.h"
259c1f1ac5d399c73f5f331bdf7b392ea7f0c44dafbsalomon@google.com#include "gl/GrGLUtil.h"
26583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.com#include "GrRenderTarget.h"
27cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "GrContext.h"
28cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
29cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
30cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GrContext;
31cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
322c8208f3a444098aee562f5a1ef620142807eda2Scroggo
331830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com#include "SkOSFile.h"
348ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo#include "SkPDFDevice.h"
358ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo#include "SkPDFDocument.h"
368ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo#include "SkStream.h"
378ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
38b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com#include "SkGPipe.h"
39b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com#include "SamplePipeControllers.h"
40b1b7f707907b8c63b955cd2aef1cc454623e3656tfarina@chromium.org#include "OverView.h"
416a12178fb32146232912fc20abb463b430f9025depoger@google.com#include "TransitionView.h"
42b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com
43a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.comSK_DEFINE_INST_COUNT(SampleWindow::DeviceManager)
44a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
451830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comextern SampleView* CreateSamplePictFileView(const char filename[]);
461830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
471830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comclass PictFileFactory : public SkViewFactory {
481830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    SkString fFilename;
491830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.compublic:
501830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    PictFileFactory(const SkString& filename) : fFilename(filename) {}
511830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    virtual SkView* operator() () const SK_OVERRIDE {
521830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        return CreateSamplePictFileView(fFilename.c_str());
531830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    }
541830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com};
551830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
56db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#define PIPE_FILEx
57db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_FILE
581f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#define FILE_PATH "/path/to/drawing.data"
591f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#endif
601f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com
61f121b0525485fb18e96c4b9dbc57594c430e42f4yangsu@google.com#define PIPE_NETx
62db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_NET
63db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkSockets.h"
64db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comSkTCPServer gServer;
65db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
66ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
67dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org#define USE_ARROWS_FOR_ZOOM true
68b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
69b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
70b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com//#define DEFAULT_TO_ANGLE 1
71b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#else
72b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com//#define DEFAULT_TO_GPU 1
73b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
74f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ANIMATING_EVENTTYPE "nextSample"
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define ANIMATING_DELAY     750
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
782eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#ifdef SK_DEBUG
79bad8c87812234117d3dc411382fca60e2e868477reed@google.com    #define FPS_REPEAT_MULTIPLIER   1
802eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#else
81bad8c87812234117d3dc411382fca60e2e868477reed@google.com    #define FPS_REPEAT_MULTIPLIER   10
822eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org#endif
83bad8c87812234117d3dc411382fca60e2e868477reed@google.com#define FPS_REPEAT_COUNT    (10 * FPS_REPEAT_MULTIPLIER)
842eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
853cec4d71e6f53fda99705427f9820d025cfbf64breed@google.comstatic SampleWindow* gSampleWindow;
863cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com
87a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.comstatic bool gShowGMBounds;
88a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com
892072db89016c4e53a648f4d4cec08b1d6be8558creed@google.comstatic void postEventToSink(SkEvent* evt, SkEventSink* sink) {
902072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    evt->setTargetID(sink->getSinkID())->post();
912072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com}
922072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com
936f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
946f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
956f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* skip_until(const char* str, const char* skip) {
966f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!str) {
976f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return NULL;
986f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
996f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return strstr(str, skip);
1006f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1016f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1026f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* skip_past(const char* str, const char* skip) {
1036f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* found = skip_until(str, skip);
1046f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!found) {
1056f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return NULL;
1066f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1076f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return found + strlen(skip);
1086f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1096f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1106f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic const char* gPrefFileName = "sampleapp_prefs.txt";
1116f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1126fc7cc23a9c33960b879f69d92d6fb0e1373e556epoger@google.comstatic bool readTitleFromPrefs(SkString* title) {
1136f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkFILEStream stream(gPrefFileName);
1146f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!stream.isValid()) {
1156f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return false;
1166f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1176f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1186f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    int len = stream.getLength();
1196f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString data(len);
1206f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    stream.read(data.writable_str(), len);
1216f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* s = data.c_str();
1226f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1236f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "curr-slide-title");
1246f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "=");
1256f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    s = skip_past(s, "\"");
1266f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    const char* stop = skip_until(s, "\"");
1276f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (stop > s) {
1286f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        title->set(s, stop - s);
1296f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        return true;
1306f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
1316f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return false;
1326f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1336f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1346fc7cc23a9c33960b879f69d92d6fb0e1373e556epoger@google.comstatic void writeTitleToPrefs(const char* title) {
1356f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkFILEWStream stream(gPrefFileName);
1366f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString data;
1376f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    data.printf("curr-slide-title = \"%s\"\n", title);
1386f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    stream.write(data.c_str(), data.size());
1396f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
1406f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
1416f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
1426f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
143098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comclass SampleWindow::DefaultDeviceManager : public SampleWindow::DeviceManager {
144098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.compublic:
145098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
146cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    DefaultDeviceManager() {
147cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
148cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurContext = NULL;
149cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurIntf = NULL;
150cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fCurRenderTarget = NULL;
151cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fMSAASampleCount = 0;
152cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
153cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        fBackend = kNone_BackEndType;
154098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
155098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
156098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual ~DefaultDeviceManager() {
157cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
158b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurContext);
159b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurIntf);
160b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurRenderTarget);
161cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
162098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
163098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
1641195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    virtual void setUpBackend(SampleWindow* win, int msaaSampleCount) {
165b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(kNone_BackEndType == fBackend);
166b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
167b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fBackend = kNone_BackEndType;
168d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
169cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
170b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        switch (win->getDeviceType()) {
171b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kRaster_DeviceType:
172b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
173b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kPicture_DeviceType:
174b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
175b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kGPU_DeviceType:
176b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
177b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kNullGPU_DeviceType:
178b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // all these guys use the native backend
179b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fBackend = kNativeGL_BackEndType;
180b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
181d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
182b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kANGLE_DeviceType:
183b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // ANGLE is really the only odd man out
184b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fBackend = kANGLE_BackEndType;
185b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
186cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
187b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            default:
188b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                SkASSERT(false);
189b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
190d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        }
191b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1921195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        bool result = win->attach(fBackend, msaaSampleCount);
193d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        if (!result) {
19474913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com            SkDebugf("Failed to initialize GL");
195b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            return;
196098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
1971195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fMSAASampleCount = msaaSampleCount;
198b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
199b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(NULL == fCurIntf);
200b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        switch (win->getDeviceType()) {
201b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kRaster_DeviceType:
202b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
203b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kPicture_DeviceType:
204b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // fallthrough
205b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kGPU_DeviceType:
206b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                // all these guys use the native interface
207b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurIntf = GrGLCreateNativeInterface();
208b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
209d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
210b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kANGLE_DeviceType:
211b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurIntf = GrGLCreateANGLEInterface();
212b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
213cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
214b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            case kNullGPU_DeviceType:
215b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurIntf = GrGLCreateNullInterface();
216b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
217b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            default:
218b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                SkASSERT(false);
219b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                break;
2206fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        }
221b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
222b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkASSERT(NULL == fCurContext);
22316e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com        fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
224b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
225b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (NULL == fCurContext || NULL == fCurIntf) {
226b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            // We need some context and interface to see results
227b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurContext);
228b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurIntf);
229098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkDebugf("Failed to setup 3D");
230b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
231b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            win->detach();
23274913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        }
233cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
234b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        // call windowSizeChanged to create the render target
235cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        this->windowSizeChanged(win);
236098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
237098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
238b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    virtual void tearDownBackend(SampleWindow *win) {
239cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
240b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurContext);
241b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurContext = NULL;
242b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
243b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurIntf);
244b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurIntf = NULL;
245b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
246b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SkSafeUnref(fCurRenderTarget);
247b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        fCurRenderTarget = NULL;
248cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
249ddd40e5e96c43ff6730745b53abf09bf0129f6d2bsalomon@google.com        win->detach();
250ddd40e5e96c43ff6730745b53abf09bf0129f6d2bsalomon@google.com        fBackend = kNone_BackEndType;
251098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
252098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
2535957f47e8de0ff55b8c0bf84984d4915c7c72825reed@google.com    virtual SkCanvas* createCanvas(SampleWindow::DeviceType dType,
2545957f47e8de0ff55b8c0bf84984d4915c7c72825reed@google.com                                   SampleWindow* win) {
255cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
25682502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        if (IsGpuDeviceType(dType) && NULL != fCurContext) {
25782502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            SkAutoTUnref<SkDevice> device(new SkGpuDevice(fCurContext, fCurRenderTarget));
25882502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            return new SkCanvas(device);
25982502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        } else
260cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
26182502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        {
26282502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            return NULL;
263098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
264098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
265098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
266098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual void publishCanvas(SampleWindow::DeviceType dType,
267098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                               SkCanvas* canvas,
268098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                               SampleWindow* win) {
269cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
270b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (fCurContext) {
271098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            // in case we have queued drawing calls
272b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            fCurContext->flush();
273b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
27482502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            if (!IsGpuDeviceType(dType)) {
275098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                // need to send the raster bits to the (gpu) window
276b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurContext->setRenderTarget(fCurRenderTarget);
277098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com                const SkBitmap& bm = win->getBitmap();
278b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                fCurRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
279fec0bc3fc13481f5bcb341ab2d2d695911f39bd4bsalomon@google.com                                             kSkia8888_GrPixelConfig,
2806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                             bm.getPixels(),
2816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                             bm.rowBytes());
282098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            }
283098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
284cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
285b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
286b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        win->present();
287098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
288098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
289098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    virtual void windowSizeChanged(SampleWindow* win) {
290cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
291b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        if (fCurContext) {
2921195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com            win->attach(fBackend, fMSAASampleCount);
293098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
29416e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com            GrBackendRenderTargetDesc desc;
295098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            desc.fWidth = SkScalarRound(win->width());
296098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            desc.fHeight = SkScalarRound(win->height());
297fec0bc3fc13481f5bcb341ab2d2d695911f39bd4bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
2983cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org            desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
299b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            GR_GL_GetIntegerv(fCurIntf, GR_GL_SAMPLES, &desc.fSampleCnt);
300b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            GR_GL_GetIntegerv(fCurIntf, GR_GL_STENCIL_BITS, &desc.fStencilBits);
301098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            GrGLint buffer;
302b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer);
303e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com            desc.fRenderTargetHandle = buffer;
304098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
305b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            SkSafeUnref(fCurRenderTarget);
30616e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com            fCurRenderTarget = fCurContext->wrapBackendRenderTarget(desc);
30774913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        }
308cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
309098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
310098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
311b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    virtual GrContext* getGrContext() {
312cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
313b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        return fCurContext;
314cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
315cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        return NULL;
316cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
317098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
3181195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
3191195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    virtual GrRenderTarget* getGrRenderTarget() SK_OVERRIDE {
320cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3211195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        return fCurRenderTarget;
322cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
323cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com        return NULL;
324cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
3251195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
3261195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
327098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comprivate:
328cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
329cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
330b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    GrContext*              fCurContext;
331b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    const GrGLInterface*    fCurIntf;
332b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    GrRenderTarget*         fCurRenderTarget;
333cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    int fMSAASampleCount;
334cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
335b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
336b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    SkOSWindow::SkBackEndTypes fBackend;
337b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
338b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    typedef SampleWindow::DeviceManager INHERITED;
339098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com};
340098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
341098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com///////////////
3422eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic const char view_inval_msg[] = "view-inval-msg";
3432eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
34462b65b0913566381db468277de07e5dd2a9237caScroggovoid SampleWindow::postInvalDelay() {
34587fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    (new SkEvent(view_inval_msg, this->getSinkID()))->postDelay(1);
3462eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
3472eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
3482eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic bool isInvalEvent(const SkEvent& evt) {
3492eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return evt.isType(view_inval_msg);
3502eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
3512eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org//////////////////
3522eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
35348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkFuncViewFactory::SkFuncViewFactory(SkViewCreateFunc func)
35448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    : fCreateFunc(func) {
35548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
35648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
3578301de132eb016f56450017c0000f9b5d913809dbsalomon@google.comSkView* SkFuncViewFactory::operator() () const {
35848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    return (*fCreateFunc)();
35948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
36048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
36148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com#include "GMSampleView.h"
36248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
36348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkGMSampleViewFactory::SkGMSampleViewFactory(GMFactoryFunc func)
36448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    : fFunc(func) {
36548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
36648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
36748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkView* SkGMSampleViewFactory::operator() () const {
36848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    return new GMSampleView(fFunc(NULL));
36948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
37048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkViewRegister* SkViewRegister::gHead;
37248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(SkViewFactory* fact) : fFact(fact) {
37348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact->ref();
37448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
37548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
37648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
37748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
37848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(SkViewCreateFunc func) {
37948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact = new SkFuncViewFactory(func);
38048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
38148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
38248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
38348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
38448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comSkViewRegister::SkViewRegister(GMFactoryFunc func) {
38548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fFact = new SkGMSampleViewFactory(func);
38648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    fChain = gHead;
38748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    gHead = this;
38848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
38948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
39048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comclass AutoUnrefArray {
39148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.compublic:
39248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    AutoUnrefArray() {}
39348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    ~AutoUnrefArray() {
39448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        int count = fObjs.count();
39548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        for (int i = 0; i < count; ++i) {
39648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            fObjs[i]->unref();
39748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        }
39848dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    }
39948dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    SkRefCnt*& push_back() { return *fObjs.append(); }
4004605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
40148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comprivate:
40248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    SkTDArray<SkRefCnt*> fObjs;
40348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com};
40448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
40548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// registers GMs as Samples
40648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// This can't be performed during static initialization because it could be
40748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// run before GMRegistry has been fully built.
40802939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comstatic void SkGMRegistyToSampleRegistry() {
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static bool gOnce;
4104605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    static AutoUnrefArray fRegisters;
41148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!gOnce) {
41348dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        const skiagm::GMRegistry* gmreg = skiagm::GMRegistry::Head();
41448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        while (gmreg) {
41548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            fRegisters.push_back() = new SkViewRegister(gmreg->factory());
41648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com            gmreg = gmreg->next();
41748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        }
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        gOnce = true;
4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
42229038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com#if 0
423f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#include <CoreFoundation/CoreFoundation.h>
424f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#include <CoreFoundation/CFURLAccess.h>
425f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
426f0b5f68807cfa18cce0647d275778147901945cdreed@google.comstatic void testpdf() {
427f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
428f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                                 kCFStringEncodingUTF8);
429f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
430f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                              kCFURLPOSIXPathStyle,
431f0b5f68807cfa18cce0647d275778147901945cdreed@google.com                                              false);
432f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFRelease(path);
433f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGRect box = CGRectMake(0, 0, 8*72, 10*72);
434f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
435f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CFRelease(url);
436f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
437f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextBeginPage(cg, &box);
438f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
439f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextFillEllipseInRect(cg, r);
440f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextEndPage(cg);
441f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    CGContextRelease(cg);
442f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
443f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    if (false) {
444f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        SkBitmap bm;
445f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        bm.setConfig(SkBitmap::kA8_Config, 64, 64);
446f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        bm.allocPixels();
447dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
448f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
449f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        SkCanvas canvas(bm);
450f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
451f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
452f0b5f68807cfa18cce0647d275778147901945cdreed@google.com}
453f0b5f68807cfa18cce0647d275778147901945cdreed@google.com#endif
454f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
455f0b5f68807cfa18cce0647d275778147901945cdreed@google.com//////////////////////////////////////////////////////////////////////////////
456f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
457569e0435af62bdb88a662fa0592f75673a17afd9reed@google.comenum FlipAxisEnum {
458569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    kFlipAxis_X = (1 << 0),
459569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    kFlipAxis_Y = (1 << 1)
460569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com};
461f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
462569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com#include "SkDrawFilter.h"
463569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
464569e0435af62bdb88a662fa0592f75673a17afd9reed@google.comclass FlagsDrawFilter : public SkDrawFilter {
465569e0435af62bdb88a662fa0592f75673a17afd9reed@google.compublic:
466db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    FlagsDrawFilter(SkOSMenu::TriState lcd, SkOSMenu::TriState aa, SkOSMenu::TriState filter,
467db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                    SkOSMenu::TriState hinting) :
46809e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com        fLCDState(lcd), fAAState(aa), fFilterState(filter), fHintingState(hinting) {}
469f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
470971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com    virtual bool filter(SkPaint* paint, Type t) {
471db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) {
472db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
473569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        }
474db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (SkOSMenu::kMixedState != fAAState) {
475db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setAntiAlias(SkOSMenu::kOnState == fAAState);
476f0b5f68807cfa18cce0647d275778147901945cdreed@google.com        }
477db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (SkOSMenu::kMixedState != fFilterState) {
478db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setFilterBitmap(SkOSMenu::kOnState == fFilterState);
479176753aa6d695ebcb76c0f82265ad69dc41dc593reed@google.com        }
480db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        if (SkOSMenu::kMixedState != fHintingState) {
481db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            paint->setHinting(SkOSMenu::kOnState == fHintingState ?
48209e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com                              SkPaint::kNormal_Hinting :
48309e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com                              SkPaint::kSlight_Hinting);
48409e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com        }
485971aca75572ed6e0c5e1cc959173dc58ca7b6b8dreed@google.com        return true;
486f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    }
487f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
488f0b5f68807cfa18cce0647d275778147901945cdreed@google.comprivate:
489db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fLCDState;
490db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fAAState;
491db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fFilterState;
492db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkOSMenu::TriState  fHintingState;
493f0b5f68807cfa18cce0647d275778147901945cdreed@google.com};
494f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
497dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org#define MAX_ZOOM_LEVEL  8
498dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org#define MIN_ZOOM_LEVEL  -8
499dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
500f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gCharEvtName[] = "SampleCode_Char_Event";
501f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gKeyEvtName[] = "SampleCode_Key_Event";
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gTitleEvtName[] = "SampleCode_Title_Event";
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
504f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic const char gFastTextEvtName[] = "SampleCode_FastText_Event";
5052072db89016c4e53a648f4d4cec08b1d6be8558creed@google.comstatic const char gUpdateWindowTitleEvtName[] = "SampleCode_UpdateWindowTitle";
506f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
507f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
508f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
509f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outUni) {
510f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outUni = evt.getFast32();
511f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
512f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
513f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
514f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
515f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
516f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
517f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
518f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
519f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (outKey) {
520f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            *outKey = (SkKey)evt.getFast32();
521f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
522f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
523f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
524f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return false;
525f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::TitleQ(const SkEvent& evt) {
5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::TitleR(SkEvent* evt, const char title[]) {
5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && TitleQ(*evt));
5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setString(gTitleEvtName, title);
5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
536db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.combool SampleCode::RequestTitle(SkView* view, SkString* title) {
537db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkEvent evt(gTitleEvtName);
538db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (view->doQuery(&evt)) {
539db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        title->set(evt.findString(gTitleEvtName));
540db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
541db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
542db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    return false;
543db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
544db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleCode::PrefSizeQ(const SkEvent& evt) {
5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(evt && PrefSizeQ(*evt));
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar size[2];
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[0] = width;
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size[1] = height;
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    evt->setScalars(gPrefSizeEvtName, 2, size);
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
557f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleCode::FastTextQ(const SkEvent& evt) {
558f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
559f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
560f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
561f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com///////////////////////////////////////////////////////////////////////////////
562f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5634417740a480786ca65379ba5b398c500ba34ee18reed@android.comstatic SkMSec gAnimTime;
564f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkMSec gAnimTimePrev;
565f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5664417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkMSec SampleCode::GetAnimTime() { return gAnimTime; }
567f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
568f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkScalar SampleCode::GetAnimSecondsDelta() {
569f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
570f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
5714417740a480786ca65379ba5b398c500ba34ee18reed@android.com
5724417740a480786ca65379ba5b398c500ba34ee18reed@android.comSkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
573f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // since gAnimTime can be up to 32 bits, we can't convert it to a float
574f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // or we'll lose the low bits. Hence we use doubles for the intermediate
575f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    // calculations
576f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double seconds = (double)gAnimTime / 1000.0;
577f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    double value = SkScalarToDouble(speed) * seconds;
5784417740a480786ca65379ba5b398c500ba34ee18reed@android.com    if (period) {
579f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        value = ::fmod(value, SkScalarToDouble(period));
5804417740a480786ca65379ba5b398c500ba34ee18reed@android.com    }
581f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return SkDoubleToScalar(value);
5824417740a480786ca65379ba5b398c500ba34ee18reed@android.com}
5834417740a480786ca65379ba5b398c500ba34ee18reed@android.com
5848500322537c5158a4632be6805b0c4210a20558bbsalomon@google.comSkScalar SampleCode::GetAnimSinScalar(SkScalar amplitude,
5858500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com                                      SkScalar periodInSec,
5868500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com                                      SkScalar phaseInSec) {
5878500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    if (!periodInSec) {
5888500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com        return 0;
5898500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    }
5908500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    double t = (double)gAnimTime / 1000.0 + phaseInSec;
5918500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    t *= SkScalarToFloat(2 * SK_ScalarPI) / periodInSec;
5928500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    amplitude = SK_ScalarHalf * amplitude;
5938500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com    return SkScalarMul(amplitude, SkDoubleToScalar(sin(t))) + amplitude;
5948500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com}
5958500322537c5158a4632be6805b0c4210a20558bbsalomon@google.com
5963cec4d71e6f53fda99705427f9820d025cfbf64breed@google.comGrContext* SampleCode::GetGr() {
5973cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com    return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
5983cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com}
5993cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com
60048dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com// some GMs rely on having a skiagm::GetGr function defined
60148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.comnamespace skiagm {
60202939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    // FIXME: this should be moved into a header
60302939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    GrContext* GetGr();
60448dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    GrContext* GetGr() { return SampleCode::GetGr(); }
60548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com}
60648dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com
6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////
6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
609f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkView* curr_view(SkWindow* wind) {
610f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkView::F2BIter iter(wind);
611f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return iter.next();
612f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
613f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
6146f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgstatic bool curr_title(SkWindow* wind, SkString* title) {
6156f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkView* view = curr_view(wind);
6166f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (view) {
6176f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        SkEvent evt(gTitleEvtName);
6186f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        if (view->doQuery(&evt)) {
6196f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            title->set(evt.findString(gTitleEvtName));
6206f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            return true;
6216f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
6226f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
6236f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    return false;
6246f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
6256f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
6262c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::setZoomCenter(float x, float y)
6272c8208f3a444098aee562f5a1ef620142807eda2Scroggo{
6282c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterX = SkFloatToScalar(x);
6292c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterY = SkFloatToScalar(y);
6302c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6320f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggobool SampleWindow::zoomIn()
6330f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6340f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    // Arbitrarily decided
6350f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fFatBitsScale == 25) return false;
6360f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fFatBitsScale++;
6370f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    this->inval(NULL);
6380f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    return true;
6390f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
6400f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
6410f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggobool SampleWindow::zoomOut()
6420f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6430f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fFatBitsScale == 1) return false;
6440f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fFatBitsScale--;
6450f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    this->inval(NULL);
6460f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    return true;
6470f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
6480f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
6490f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggovoid SampleWindow::updatePointer(int x, int y)
6500f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
6510f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseX = x;
6520f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseY = y;
6530f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (fShowZoomer) {
6540f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        this->inval(NULL);
6550f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
6560f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
6570f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
658098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comstatic inline SampleWindow::DeviceType cycle_devicetype(SampleWindow::DeviceType ct) {
659098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    static const SampleWindow::DeviceType gCT[] = {
660098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kPicture_DeviceType,
661cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
662098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kGPU_DeviceType,
663b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
664b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        SampleWindow::kANGLE_DeviceType,
665cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
66674913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        SampleWindow::kRaster_DeviceType, // skip the null gpu device in normal cycling
667cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
668098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        SampleWindow::kRaster_DeviceType
6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
670cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gCT) == SampleWindow::kDeviceTypeCnt, array_size_mismatch);
6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gCT[ct];
6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6748570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.comstatic void usage(const char * argv0) {
6754605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    SkDebugf("%s [--slide sampleName] [-i resourcePath] [--msaa sampleCount] [--pictureDir dirPath] [--picture path]\n", argv0);
6768570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    SkDebugf("    sampleName: sample at which to start.\n");
6778570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    SkDebugf("    resourcePath: directory that stores image resources.\n");
6781195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    SkDebugf("    msaa: request multisampling with the given sample count.\n");
6794605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    SkDebugf("    dirPath: path to directory skia pictures are read from\n");
6804605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    SkDebugf("    path: path to skia picture\n");
6818570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com}
6828570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
6834605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.comSampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager)
6844750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com    : INHERITED(hwnd)
6854750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com    , fDevManager(NULL) {
6868570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
6871830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    this->registerPictFileSamples(argv, argc);
6884605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->registerPictFileSample(argv, argc);
68976d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    SkGMRegistyToSampleRegistry();
69076d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    {
69176d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        const SkViewRegister* reg = SkViewRegister::Head();
69276d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        while (reg) {
69376d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            *fSamples.append() = reg->factory();
69476d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            reg = reg->next();
69576d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        }
69676d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com    }
69776d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com
6988570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    const char* resourcePath = NULL;
6998570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    fCurrIndex = -1;
7001195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fMSAASampleCount = 0;
7018570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
7028570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    const char* const commandName = argv[0];
7038570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    char* const* stop = argv + argc;
7048570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    for (++argv; argv < stop; ++argv) {
7058570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        if (strcmp(*argv, "-i") == 0) {
7068570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            argv++;
7078570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            if (argv < stop && **argv) {
7088570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com                resourcePath = *argv;
7098570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            }
71076d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com        } else if (strcmp(*argv, "--slide") == 0) {
71176d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            argv++;
71276d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            if (argv < stop && **argv) {
71376d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com                fCurrIndex = findByTitle(*argv);
71476d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com                if (fCurrIndex < 0) {
71576d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com                    fprintf(stderr, "Unknown sample \"%s\"\n", *argv);
7167265e725555098637498db2f397623d7991ceb4brobertphillips@google.com                    listTitles();
71776d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com                }
7188570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            }
7191195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        } else if (strcmp(*argv, "--msaa") == 0) {
7201195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com            ++argv;
7211195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com            if (argv < stop && **argv) {
7221195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                fMSAASampleCount = atoi(*argv);
7231195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com            }
7247265e725555098637498db2f397623d7991ceb4brobertphillips@google.com        } else if (strcmp(*argv, "--list") == 0) {
7257265e725555098637498db2f397623d7991ceb4brobertphillips@google.com            listTitles();
7261195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        }
727d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        else {
72876d4021ee1bfbf31da274e9feb4c675cfd86e6d3robertphillips@google.com            usage(commandName);
7298570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        }
7308570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
7318570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
7328570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    if (fCurrIndex < 0) {
7338570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        SkString title;
7348570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        if (readTitleFromPrefs(&title)) {
7358570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com            fCurrIndex = findByTitle(title.c_str());
7368570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        }
7378570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
7388570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
7398570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    if (fCurrIndex < 0) {
7408570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com        fCurrIndex = 0;
7418570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    }
7428570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
7433cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com    gSampleWindow = this;
7443cec4d71e6f53fda99705427f9820d025cfbf64breed@google.com
7451f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#ifdef  PIPE_FILE
7461f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    //Clear existing file or create file if it doesn't exist
7471f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    FILE* f = fopen(FILE_PATH, "wb");
7481f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com    fclose(f);
7491f3942110a6fcec86eb411b49eab16d2bd91eb5byangsu@google.com#endif
7504605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPicture = NULL;
7524605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
753bd8d7adb0ac9533a04e7b7a481371d4c66bbbc9brobertphillips@google.com    fDeviceType = kRaster_DeviceType;
754b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
755b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if DEFAULT_TO_GPU
756b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = kGPU_DeviceType;
757b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
758b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE && DEFAULT_TO_ANGLE
759b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = kANGLE_DeviceType;
76053e96a14cac520c1fd071ad65d80b5bacc5c4e28robertphillips@google.com#endif
761b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fUseClip = false;
763e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    fNClip = false;
7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fAnimating = false;
7656c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    fRotate = false;
766e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    fPerspAnim = false;
767e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    fPerspAnimTime = 0;
7686c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    fScale = false;
769f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    fRequestGrabImage = false;
770b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fPipeState = SkOSMenu::kOffState;
77167b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    fTilingState = SkOSMenu::kOffState;
77285cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com    fTileCount.set(1, 1);
7732eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    fMeasureFPS = false;
774db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fLCDState = SkOSMenu::kMixedState;
775db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fAAState = SkOSMenu::kMixedState;
776db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fFilterState = SkOSMenu::kMixedState;
777db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fHintingState = SkOSMenu::kMixedState;
778569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    fFlipAxis = 0;
7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fScrollTestX = fScrollTestY = 0;
7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7810f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fMouseX = fMouseY = 0;
7823ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org    fFatBitsScale = 8;
7830f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
7840f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fShowZoomer = false;
7854605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
786dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    fZoomLevel = 0;
787dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    fZoomScale = SK_Scalar1;
7884605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
789db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fMagnify = false;
7904605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
7918ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fSaveToPdf = false;
7928ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fPdfCanvas = NULL;
7938ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
794db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fTransitionNext = 6;
795db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    fTransitionPrev = 2;
7964605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
797921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    int sinkID = this->getSinkID();
7987dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu = new SkOSMenu;
7997dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->setTitle("Global Settings");
800db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    int itemID;
8014605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
8024605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Device Type", "Device Type", sinkID, 0,
8034605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Raster", "Picture", "OpenGL",
804b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
805b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                                "ANGLE",
806b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#endif
807b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com                                NULL);
8087dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'd');
8097dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("AA", "AA", sinkID, fAAState);
8107dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'b');
8117dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("LCD", "LCD", sinkID, fLCDState);
8127dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'l');
8137dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("Filter", "Filter", sinkID, fFilterState);
8147dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'n');
8157dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendTriState("Hinting", "Hinting", sinkID, fHintingState);
8167dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'h');
81767b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
818b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fUsePipeMenuItemID = fAppMenu->appendTriState("Pipe", "Pipe" , sinkID,
8194605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                                  fPipeState);
820b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    fAppMenu->assignKeyEquivalentToItem(fUsePipeMenuItemID, 'P');
82167b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
82267b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    itemID = fAppMenu->appendTriState("Tiling", "Tiling", sinkID, fTilingState);
82367b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 't');
82467b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com
8254605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Slide Show", "Slide Show" , sinkID, false);
8264605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'a');
8274605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Clip", "Clip" , sinkID, fUseClip);
8287dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'c');
8294605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID = fAppMenu->appendSwitch("Flip X", "Flip X" , sinkID, false);
8307dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'x');
8317dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Flip Y", "Flip Y" , sinkID, false);
8327dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'y');
8337dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Zoomer", "Zoomer" , sinkID, fShowZoomer);
8347dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'z');
8357dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendSwitch("Magnify", "Magnify" , sinkID, fMagnify);
8367dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'm');
8374605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Transition-Next", "Transition-Next", sinkID,
8384605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                fTransitionNext, "Up", "Up and Right", "Right",
8394605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Down and Right", "Down", "Down and Left",
840db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                "Left", "Up and Left", NULL);
8417dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'j');
8424605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    itemID =fAppMenu->appendList("Transition-Prev", "Transition-Prev", sinkID,
8434605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                fTransitionPrev, "Up", "Up and Right", "Right",
8444605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                "Down and Right", "Down", "Down and Left",
845db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                "Left", "Up and Left", NULL);
8467dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'k');
8477dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    itemID = fAppMenu->appendAction("Save to PDF", sinkID);
8487dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fAppMenu->assignKeyEquivalentToItem(itemID, 'e');
8494605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
8507dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->addMenu(fAppMenu);
8517dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fSlideMenu = new SkOSMenu;
8527dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->addMenu(fSlideMenu);
8534605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
8542fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com//    this->setConfig(SkBitmap::kRGB_565_Config);
8552fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    this->setConfig(SkBitmap::kARGB_8888_Config);
8562fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    this->setVisibleP(true);
857f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    this->setClipToBounds(false);
8588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8598570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com    skiagm::GM::SetResourcePath(resourcePath);
8608570b5c8695052378491b0c61e745d736fe85c8drobertphillips@google.com
86148dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    this->loadView((*fSamples[fCurrIndex])());
8624605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
863840e9f3776ea99d9c1cfe5ccc0b85f3db3da9affbsalomon@google.com    fPDFData = NULL;
864f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
865098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (NULL == devManager) {
866098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        fDevManager = new DefaultDeviceManager();
867098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    } else {
868098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        devManager->ref();
869098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        fDevManager = devManager;
870098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    }
8711195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fDevManager->setUpBackend(this, fMSAASampleCount);
872098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
873b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // If another constructor set our dimensions, ensure that our
874b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // onSizeChange gets called.
875b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    if (this->height() && this->width()) {
876b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo        this->onSizeChange();
877b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    }
8782072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com
8792072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // can't call this synchronously, since it may require a subclass to
8802072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // to implement, or the caller may need us to have returned from the
8812072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    // constructor first. Hence we post an event to ourselves.
8822072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com//    this->updateTitle();
8832072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    postEventToSink(new SkEvent(gUpdateWindowTitleEvtName), this);
8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSampleWindow::~SampleWindow() {
8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    delete fPicture;
8888ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    delete fPdfCanvas;
8890f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    fTypeface->unref();
89029038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com
891098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    SkSafeUnref(fDevManager);
8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8941830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comstatic void make_filepath(SkString* path, const char* dir, const SkString& name) {
8951830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    size_t len = strlen(dir);
8961830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    path->set(dir);
8971830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    if (len > 0 && dir[len - 1] != '/') {
8981830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        path->append("/");
8991830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    }
9001830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    path->append(name);
9011830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com}
9021830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
9034605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.comvoid SampleWindow::registerPictFileSample(char** argv, int argc) {
9044605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    const char* pict = NULL;
9054605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
9064605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    for (int i = 0; i < argc; ++i) {
9074605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        if (!strcmp(argv[i], "--picture")) {
9084605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com            i += 1;
9094605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com            if (i < argc) {
9104605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                pict = argv[i];
9114605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                break;
9124605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com            }
9134605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        }
9144605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
9154605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    if (pict) {
9164605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        SkString path(pict);
9174605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        *fSamples.append() = new PictFileFactory(path);
9184605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
9194605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com}
9204605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
9211830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.comvoid SampleWindow::registerPictFileSamples(char** argv, int argc) {
9221830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    const char* pictDir = NULL;
9231830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
9241830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    for (int i = 0; i < argc; ++i) {
9251830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        if (!strcmp(argv[i], "--pictureDir")) {
9261830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            i += 1;
9271830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            if (i < argc) {
9281830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com                pictDir = argv[i];
9291830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com                break;
9301830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            }
9311830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        }
9321830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    }
9331830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    if (pictDir) {
9341830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        SkOSFile::Iter iter(pictDir, "skp");
9351830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        SkString filename;
9361830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        while (iter.next(&filename)) {
9371830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            SkString path;
9381830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            make_filepath(&path, pictDir, filename);
9391830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com            *fSamples.append() = new PictFileFactory(path);
9401830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com        }
9411830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com    }
9421830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com}
9431830c7aa3c4045af438fb24ee0bd22598f1bfca7reed@google.com
9446f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.orgint SampleWindow::findByTitle(const char title[]) {
9456f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    int i, count = fSamples.count();
9466f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    for (i = 0; i < count; i++) {
9476f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        if (getSampleTitle(i).equals(title)) {
9486f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            return i;
9496f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
9506f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    }
951dd52caaa093845c7c5157be78d94feb72f9cb155mike@reedtribe.org    return -1;
9526f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org}
9536f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org
9547265e725555098637498db2f397623d7991ceb4brobertphillips@google.comvoid SampleWindow::listTitles() {
9557265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    int count = fSamples.count();
9567265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    SkDebugf("All Slides:\n");
9577265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    for (int i = 0; i < count; i++) {
9587265e725555098637498db2f397623d7991ceb4brobertphillips@google.com        SkDebugf("    %s\n", getSampleTitle(i).c_str());
9597265e725555098637498db2f397623d7991ceb4brobertphillips@google.com    }
9607265e725555098637498db2f397623d7991ceb4brobertphillips@google.com}
9617265e725555098637498db2f397623d7991ceb4brobertphillips@google.com
96255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic SkBitmap capture_bitmap(SkCanvas* canvas) {
96355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkBitmap bm;
96455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
96555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    src.copyTo(&bm, src.config());
96655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return bm;
96755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
96855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
96955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.comstatic bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
97055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                        SkBitmap* diff) {
97155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
9722e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
97355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp0(src);
97455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    SkAutoLockPixels alp1(orig);
97555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    for (int y = 0; y < src.height(); y++) {
97655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* srcP = src.getAddr(0, y);
97755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        const void* origP = orig.getAddr(0, y);
97855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        size_t bytes = src.width() * src.bytesPerPixel();
97955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (memcmp(srcP, origP, bytes)) {
98055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkDebugf("---------- difference on line %d\n", y);
98155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            return true;
98255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
98355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    }
98455e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com    return false;
98555e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com}
98655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com
9870f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggostatic void drawText(SkCanvas* canvas, SkString string, SkScalar left, SkScalar top, SkPaint& paint)
9880f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo{
9890f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkColor desiredColor = paint.getColor();
9900f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.setColor(SK_ColorWHITE);
9910f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    const char* c_str = string.c_str();
9920f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    size_t size = string.size();
9930f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkRect bounds;
9940f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.measureText(c_str, size, &bounds);
9950f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    bounds.offset(left, top);
9960f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    SkScalar inset = SkIntToScalar(-2);
9970f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    bounds.inset(inset, inset);
9980f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    canvas->drawRect(bounds, paint);
9990f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (desiredColor != SK_ColorBLACK) {
10000f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
10010f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawText(c_str, size, left + SK_Scalar1, top + SK_Scalar1, paint);
10020f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
10030f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    paint.setColor(desiredColor);
10040f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    canvas->drawText(c_str, size, left, top, paint);
10050f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo}
10060f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo
10074417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define XCLIP_N  8
10084417740a480786ca65379ba5b398c500ba34ee18reed@android.com#define YCLIP_N  8
1009e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
1010e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.comvoid SampleWindow::draw(SkCanvas* canvas) {
10114417740a480786ca65379ba5b398c500ba34ee18reed@android.com    // update the animation time
1012e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (!gAnimTimePrev && !gAnimTime) {
1013e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        // first time make delta be 0
1014e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTime = SkTime::GetMSecs();
1015e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTimePrev = gAnimTime;
1016e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    } else {
1017e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTimePrev = gAnimTime;
1018e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        gAnimTime = SkTime::GetMSecs();
1019e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
10204605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1021f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fGesture.isActive()) {
1022f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
102352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
10244605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1025796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS) {
1026796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        fMeasureFPS_Time = 0;
1027796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    }
1028796763e0b2c06a7789185322561a1135e5484688djsollen@google.com
1029e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
103055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        this->INHERITED::draw(canvas);
103155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap orig = capture_bitmap(canvas);
1032e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
1033e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar w = this->width();
1034e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar h = this->height();
1035e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar cw = w / XCLIP_N;
1036e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        const SkScalar ch = h / YCLIP_N;
1037e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        for (int y = 0; y < YCLIP_N; y++) {
103855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            SkRect r;
103955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fTop = y * ch;
104055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            r.fBottom = (y + 1) * ch;
104155e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            if (y == YCLIP_N - 1) {
104255e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fBottom = h;
104355e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com            }
1044e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            for (int x = 0; x < XCLIP_N; x++) {
1045e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                SkAutoCanvasRestore acr(canvas, true);
104655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fLeft = x * cw;
104755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                r.fRight = (x + 1) * cw;
104855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                if (x == XCLIP_N - 1) {
104955e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                    r.fRight = w;
105055e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com                }
1051e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                canvas->clipRect(r);
1052e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com                this->INHERITED::draw(canvas);
1053e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com            }
1054e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        }
10552e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
105655e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        SkBitmap diff;
105755e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        if (bitmap_diff(canvas, orig, &diff)) {
105855e76b209c9249308a9ba3d75c2472dd55e9d298reed@android.com        }
1059e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    } else {
106085cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        const SkScalar cw = SkScalarDiv(this->width(), SkIntToScalar(fTileCount.width()));
106185cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        const SkScalar ch = SkScalarDiv(this->height(), SkIntToScalar(fTileCount.height()));
1062ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
106385cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        for (int y = 0; y < fTileCount.height(); ++y) {
106485cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            for (int x = 0; x < fTileCount.width(); ++x) {
106585cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                SkAutoCanvasRestore acr(canvas, true);
106685cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                canvas->clipRect(SkRect::MakeXYWH(x * cw, y * ch, cw, ch));
106785cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                this->INHERITED::draw(canvas);
106885cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            }
106985cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        }
1070ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
107185cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        if (!fTileCount.equals(1, 1)) {
107285cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            SkPaint paint;
107385cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            paint.setColor(0x60FF00FF);
107485cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            paint.setStyle(SkPaint::kStroke_Style);
107585cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            for (int y = 0; y < fTileCount.height(); ++y) {
107685cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                for (int x = 0; x < fTileCount.width(); ++x) {
107785cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                    canvas->drawRect(SkRect::MakeXYWH(x * cw, y * ch, cw, ch), paint);
107885cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com                }
107985cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com            }
108085cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        }
1081e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
1082098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (fShowZoomer && !fSaveToPdf) {
10833272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo        showZoomer(canvas);
10843272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo    }
1085db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (fMagnify && !fSaveToPdf) {
1086db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        magnify(canvas);
1087db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
10884605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1089796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS && fMeasureFPS_Time) {
1090796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        this->updateTitle();
1091796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        this->postInvalDelay();
1092796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    }
1093796763e0b2c06a7789185322561a1135e5484688djsollen@google.com
109429038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    // do this last
1095098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    fDevManager->publishCanvas(fDeviceType, canvas, this);
10963272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo}
10973272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggo
1098db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic float clipW = 200;
1099db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic float clipH = 200;
1100db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleWindow::magnify(SkCanvas* canvas) {
1101db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkRect r;
1102db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    int count = canvas->save();
11034605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1104db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkMatrix m = canvas->getTotalMatrix();
110507ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    if (!m.invert(&m)) {
110607ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com        return;
110707ef911f18e30566d8a9d790e0bd69a836fd9d24robertphillips@google.com    }
1108db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkPoint offset, center;
1109820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    SkScalar mouseX = fMouseX * SK_Scalar1;
1110820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    SkScalar mouseY = fMouseY * SK_Scalar1;
1111820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.mapXY(mouseX - clipW/2, mouseY - clipH/2, &offset);
1112820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.mapXY(mouseX, mouseY, &center);
11134605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1114db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    r.set(0, 0, clipW * m.getScaleX(), clipH * m.getScaleX());
1115db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    r.offset(offset.fX, offset.fY);
11164605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1117db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SkPaint paint;
1118db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    paint.setColor(0xFF66AAEE);
1119db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    paint.setStyle(SkPaint::kStroke_Style);
1120820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    paint.setStrokeWidth(10.f * m.getScaleX());
1121db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    //lense offset
1122db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    //canvas->translate(0, -250);
1123db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->drawRect(r, paint);
1124db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->clipRect(r);
11254605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1126db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m = canvas->getTotalMatrix();
1127db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m.setTranslate(-center.fX, -center.fY);
1128820e80ad6390e120d4991a5280d0452ec87beaebbsalomon@google.com    m.postScale(0.5f * fFatBitsScale, 0.5f * fFatBitsScale);
1129db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    m.postTranslate(center.fX, center.fY);
1130db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->concat(m);
11314605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1132db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    this->INHERITED::draw(canvas);
11334605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1134db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    canvas->restoreToCount(count);
1135db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
1136db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
11373272ba8abcf322f5e9bcf2f7f2dcddaf68550268Scroggovoid SampleWindow::showZoomer(SkCanvas* canvas) {
11380f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        int count = canvas->save();
11390f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->resetMatrix();
11400f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Ensure the mouse position is on screen.
1141261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com        int width = SkScalarRound(this->width());
1142261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com        int height = SkScalarRound(this->height());
11430f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (fMouseX >= width) fMouseX = width - 1;
11440f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        else if (fMouseX < 0) fMouseX = 0;
11450f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (fMouseY >= height) fMouseY = height - 1;
11460f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        else if (fMouseY < 0) fMouseY = 0;
1147b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com
11480f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkBitmap bitmap = capture_bitmap(canvas);
1149b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com        bitmap.lockPixels();
1150b36334d46a488c2d4104a2cabf406cac0585f27ereed@google.com
11510f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Find the size of the zoomed in view, forced to be odd, so the examined pixel is in the middle.
11523ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org        int zoomedWidth = (width >> 1) | 1;
11533ce59dc4999de5d6c6913af662c8b0b8020a4ef7mike@reedtribe.org        int zoomedHeight = (height >> 1) | 1;
11540f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkIRect src;
11550f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        src.set(0, 0, zoomedWidth / fFatBitsScale, zoomedHeight / fFatBitsScale);
11560f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        src.offset(fMouseX - (src.width()>>1), fMouseY - (src.height()>>1));
11570f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect dest;
11580f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        dest.set(0, 0, SkIntToScalar(zoomedWidth), SkIntToScalar(zoomedHeight));
11590f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        dest.offset(SkIntToScalar(width - zoomedWidth), SkIntToScalar(height - zoomedHeight));
11600f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkPaint paint;
11610f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Clear the background behind our zoomed in view
11620f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorWHITE);
11630f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawRect(dest, paint);
11640f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawBitmapRect(bitmap, &src, dest);
11650f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
11660f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setStyle(SkPaint::kStroke_Style);
11670f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Draw a border around the pixel in the middle
11680f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect originalPixel;
11690f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        originalPixel.set(SkIntToScalar(fMouseX), SkIntToScalar(fMouseY), SkIntToScalar(fMouseX + 1), SkIntToScalar(fMouseY + 1));
11700f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkMatrix matrix;
11710f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkRect scalarSrc;
11720f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        scalarSrc.set(src);
11730f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkColor color = bitmap.getColor(fMouseX, fMouseY);
11740f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        if (matrix.setRectToRect(scalarSrc, dest, SkMatrix::kFill_ScaleToFit)) {
11750f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            SkRect pixel;
11760f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            matrix.mapRect(&pixel, originalPixel);
11770f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            // TODO Perhaps measure the values and make the outline white if it's "dark"
11780f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            if (color == SK_ColorBLACK) {
11790f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo                paint.setColor(SK_ColorWHITE);
11800f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            }
11810f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo            canvas->drawRect(pixel, paint);
11820f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        }
11830f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLACK);
11840f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Draw a border around the destination rectangle
11850f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->drawRect(dest, paint);
11860f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setStyle(SkPaint::kStrokeAndFill_Style);
11870f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Identify the pixel and its color on screen
11880f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setTypeface(fTypeface);
11890f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setAntiAlias(true);
11900f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar lineHeight = paint.getFontMetrics(NULL);
11910f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkString string;
11920f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("(%i, %i)", fMouseX, fMouseY);
11930f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar left = dest.fLeft + SkIntToScalar(3);
11940f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        SkScalar i = SK_Scalar1;
11950f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
11960f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Alpha
11970f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
11980f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
11990f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("A: %X", SkColorGetA(color));
12000f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12010f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Red
12020f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12030f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12040f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("R: %X", SkColorGetR(color));
12050f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorRED);
12060f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12070f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Green
12080f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12090f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12100f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("G: %X", SkColorGetG(color));
12110f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorGREEN);
12120f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12130f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        // Blue
12140f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        i += SK_Scalar1;
12150f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.reset();
12160f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        string.appendf("B: %X", SkColorGetB(color));
12170f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        paint.setColor(SK_ColorBLUE);
12180f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
12190f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        canvas->restoreToCount(count);
1220e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com}
1221e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com
12228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onDraw(SkCanvas* canvas) {
12238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h"
12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
122702939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#if 0 // UNUSED
12288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void reverseRedAndBlue(const SkBitmap& bm) {
12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config);
12308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* p = (uint8_t*)bm.getPixels();
12318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t* stop = p + bm.getSize();
12328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (p < stop) {
12338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply
12348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned scale = SkAlpha255To256(p[3]);
12358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned r = p[2];
12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        unsigned b = p[0];
12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[0] = SkAlphaMul(r, scale);
12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[1] = SkAlphaMul(p[1], scale);
12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p[2] = SkAlphaMul(b, scale);
12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p += 4;
12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
12428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
124302939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#endif
12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12458ac0d542b0226e68b0faa935b3402ffc91409a02Scroggovoid SampleWindow::saveToPdf()
12468ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo{
12478ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    fSaveToPdf = true;
12488ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    this->inval(NULL);
12498ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo}
12508ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
12528ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    if (fSaveToPdf) {
12538ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        const SkBitmap& bmp = canvas->getDevice()->accessBitmap(false);
12548ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkISize size = SkISize::Make(bmp.width(), bmp.height());
12558ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDevice* pdfDevice = new SkPDFDevice(size, size,
12568ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo                canvas->getTotalMatrix());
12578ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fPdfCanvas = new SkCanvas(pdfDevice);
12588ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        pdfDevice->unref();
12598ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        canvas = fPdfCanvas;
126082502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com    } else if (kPicture_DeviceType == fDeviceType) {
126182502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        fPicture = new SkPicture;
126282502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        canvas = fPicture->beginRecording(9999, 9999);
12638ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    } else {
1264cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
126582502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        if (kNullGPU_DeviceType != fDeviceType)
1266cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
126782502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        {
126882502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com            canvas = this->INHERITED::beforeChildren(canvas);
1269ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fUseClip) {
12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        canvas->drawColor(0xFFFF88FF);
1274045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com        canvas->clipPath(fClipPath, SkRegion::kIntersect_Op, true);
12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return canvas;
12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void paint_rgn(const SkBitmap& bm, const SkIRect& r,
12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                      const SkRegion& rgn) {
12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkCanvas    canvas(bm);
12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRegion    inval(rgn);
12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
12858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    inval.translate(r.fLeft, r.fTop);
12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.clipRegion(inval);
12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    canvas.drawColor(0xFFFF8080);
12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1289501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#include "SkData.h"
12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::afterChildren(SkCanvas* orig) {
12918ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    if (fSaveToPdf) {
12928ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fSaveToPdf = false;
12938ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        if (fShowZoomer) {
12948ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            showZoomer(fPdfCanvas);
12958ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        }
12968ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkString name;
12978ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        name.printf("%s.pdf", this->getTitle());
12988ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDocument doc;
12998ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkPDFDevice* device = static_cast<SkPDFDevice*>(fPdfCanvas->getDevice());
13008ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        doc.appendPage(device);
130156c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
13028ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        name.prepend("/sdcard/");
13038ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo#endif
13044605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1305501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#ifdef SK_BUILD_FOR_IOS
1306501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com        SkDynamicMemoryWStream mstream;
1307501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com        doc.emitPDF(&mstream);
1308ae8a2e5cba553267b189b8b5cae40330c4ff5bdbyangsu@google.com        fPDFData = mstream.copyToData();
1309501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com#endif
13108ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        SkFILEWStream stream(name.c_str());
13118ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        if (stream.isValid()) {
13128ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            doc.emitPDF(&stream);
13138ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            const char* desc = "File saved from Skia SampleApp";
13148ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo            this->onPDFSaved(this->getTitle(), desc, name.c_str());
13158ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        }
13164605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
13178ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        delete fPdfCanvas;
13188ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        fPdfCanvas = NULL;
13198ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo
13208ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        // We took over the draw calls in order to create the PDF, so we need
13218ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        // to redraw.
13228ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        this->inval(NULL);
13238ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo        return;
13248ac0d542b0226e68b0faa935b3402ffc91409a02Scroggo    }
13254605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (fRequestGrabImage) {
1327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        fRequestGrabImage = false;
13282e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
132929038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        SkDevice* device = orig->getDevice();
1330669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com        SkBitmap bmp;
1331669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com        if (device->accessBitmap(false).copyTo(&bmp, SkBitmap::kARGB_8888_Config)) {
1332f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            static int gSampleGrabCounter;
1333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkString name;
13347c57e0e7ccb05a4b7ce05b883ba06380d5578881reed@google.com            name.printf("sample_grab_%d.png", gSampleGrabCounter++);
1335669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com            SkImageEncoder::EncodeFile(name.c_str(), bmp,
1336f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                                       SkImageEncoder::kPNG_Type, 100);
1337f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1338f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1339f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
1340098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    if (kPicture_DeviceType == fDeviceType) {
1341098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        if (true) {
1342098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkPicture* pict = new SkPicture(*fPicture);
1343098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            fPicture->unref();
1344e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com            this->installDrawFilter(orig);
1345098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            orig->drawPicture(*pict);
1346098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            pict->unref();
1347098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        } else if (true) {
1348098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkDynamicMemoryWStream ostream;
1349098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            fPicture->serialize(&ostream);
1350098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            fPicture->unref();
1351098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com
1352098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkAutoDataUnref data(ostream.copyToData());
135359f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com            SkMemoryStream istream(data->data(), data->size());
1354098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            SkPicture pict(&istream);
1355098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            orig->drawPicture(pict);
1356098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        } else {
1357098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            fPicture->draw(orig);
1358098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com            fPicture->unref();
1359098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        }
1360098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com        fPicture = NULL;
13618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
13622e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
136317d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    // Do this after presentGL and other finishing, rather than in afterChild
1364796763e0b2c06a7789185322561a1135e5484688djsollen@google.com    if (fMeasureFPS && fMeasureFPS_StartTime) {
1365796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        fMeasureFPS_Time += SkTime::GetMSecs() - fMeasureFPS_StartTime;
136617d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    }
136717d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com
136817d7aec8967f7e2f6bb420c6647be11285fac2f1reed@google.com    //    if ((fScrollTestX | fScrollTestY) != 0)
1369f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (false) {
13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
13718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dx = fScrollTestX * 7;
13728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        int dy = fScrollTestY * 7;
13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkIRect r;
13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRegion inval;
13752e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(50, 50, 50+100, 50+100);
13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bm.scrollRect(&r, dx, dy, &inval);
13788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        paint_rgn(bm, r, inval);
1379ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    }
13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13826c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::beforeChild(SkView* child, SkCanvas* canvas) {
13836c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fScale) {
13846c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar scale = SK_Scalar1 * 7 / 10;
13856c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cx = this->width() / 2;
13866c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cy = this->height() / 2;
13876c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(cx, cy);
13886c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->scale(scale, scale);
13896c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(-cx, -cy);
13906c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
13916c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
13926c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cx = this->width() / 2;
13936c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        SkScalar cy = this->height() / 2;
13946c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(cx, cy);
13956c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->rotate(SkIntToScalar(30));
13966c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        canvas->translate(-cx, -cy);
13976c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
1398e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (fPerspAnim) {
13996fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        fPerspAnimTime += SampleCode::GetAnimSecondsDelta();
14006fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com
14016fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        static const SkScalar gAnimPeriod = 10 * SK_Scalar1;
14026fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        static const SkScalar gAnimMag = SK_Scalar1 / 1000;
14036fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        SkScalar t = SkScalarMod(fPerspAnimTime, gAnimPeriod);
14046fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        if (SkScalarFloorToInt(SkScalarDiv(fPerspAnimTime, gAnimPeriod)) & 0x1) {
14056fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            t = gAnimPeriod - t;
14066fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        }
14076fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        t = 2 * t - gAnimPeriod;
14086fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        t = SkScalarMul(SkScalarDiv(t, gAnimPeriod), gAnimMag);
14096fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        SkMatrix m;
14106fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        m.reset();
14116fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        m.setPerspY(t);
1412e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        canvas->concat(m);
1413e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
1414f0b5f68807cfa18cce0647d275778147901945cdreed@google.com
1415e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com    this->installDrawFilter(canvas);
14162eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
14172eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (fMeasureFPS) {
1418f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        if (SampleView::SetRepeatDraw(child, FPS_REPEAT_COUNT)) {
1419796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            fMeasureFPS_StartTime = SkTime::GetMSecs();
1420f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        }
1421f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    } else {
1422f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com        (void)SampleView::SetRepeatDraw(child, 1);
14232eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
1424e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (fPerspAnim) {
1425e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        this->inval(NULL);
1426e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
14276c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
14286c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
14296c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.comvoid SampleWindow::afterChild(SkView* child, SkCanvas* canvas) {
1430f0b5f68807cfa18cce0647d275778147901945cdreed@google.com    canvas->setDrawFilter(NULL);
14316c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com}
14326c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com
14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkBitmap::Config gConfigCycle[] = {
14348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // none -> none
14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // a1 -> none
14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // a8 -> none
14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kNo_Config,           // index8 -> none
14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kARGB_4444_Config,    // 565 -> 4444
14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kARGB_8888_Config,    // 4444 -> 8888
14408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkBitmap::kRGB_565_Config       // 8888 -> 565
14418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
14428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkBitmap::Config cycle_configs(SkBitmap::Config c) {
14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gConfigCycle[c];
14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1447e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.comvoid SampleWindow::changeZoomLevel(float delta) {
1448e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com    fZoomLevel += SkFloatToScalar(delta);
1449dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (fZoomLevel > 0) {
1450e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomLevel = SkMinScalar(fZoomLevel, MAX_ZOOM_LEVEL);
1451e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomScale = fZoomLevel + SK_Scalar1;
1452dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    } else if (fZoomLevel < 0) {
1453e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomLevel = SkMaxScalar(fZoomLevel, MIN_ZOOM_LEVEL);
1454e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        fZoomScale = SK_Scalar1 / (SK_Scalar1 - fZoomLevel);
1455dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    } else {
1456dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        fZoomScale = SK_Scalar1;
1457dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
1458f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->updateMatrix();
1459f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com}
1460dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
1461f03bb566e25ace918f8fdda3cb8426626a00894creed@google.comvoid SampleWindow::updateMatrix(){
1462f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    SkMatrix m;
1463f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.reset();
1464f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fZoomLevel) {
1465f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkPoint center;
1466f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        //m = this->getLocalMatrix();//.invert(&m);
1467f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.mapXY(fZoomCenterX, fZoomCenterY, &center);
1468f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkScalar cx = center.fX;
1469f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        SkScalar cy = center.fY;
14704605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1471f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.setTranslate(-cx, -cy);
1472f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.postScale(fZoomScale, fZoomScale);
1473f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.postTranslate(cx, cy);
1474f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
14754605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1476f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    if (fFlipAxis) {
1477f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.preTranslate(fZoomCenterX, fZoomCenterY);
1478f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        if (fFlipAxis & kFlipAxis_X) {
1479f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            m.preScale(-SK_Scalar1, SK_Scalar1);
1480f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
1481f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        if (fFlipAxis & kFlipAxis_Y) {
1482f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com            m.preScale(SK_Scalar1, -SK_Scalar1);
1483f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        }
1484f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        m.preTranslate(-fZoomCenterX, -fZoomCenterY);
1485f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        //canvas->concat(m);
1486f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    }
1487f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    // Apply any gesture matrix
1488f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.preConcat(fGesture.localM());
1489f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    m.preConcat(fGesture.globalM());
14904605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1491f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com    this->setLocalMatrix(m);
14924605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
1493e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com    this->updateTitle();
1494dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    this->inval(NULL);
1495dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org}
14962c8208f3a444098aee562f5a1ef620142807eda2Scroggobool SampleWindow::previousSample() {
149762b65b0913566381db468277de07e5dd2a9237caScroggo    fCurrIndex = (fCurrIndex - 1 + fSamples.count()) % fSamples.count();
14984605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
1499db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     fTransitionPrev));
15002c8208f3a444098aee562f5a1ef620142807eda2Scroggo    return true;
15012c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
15022c8208f3a444098aee562f5a1ef620142807eda2Scroggo
15038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::nextSample() {
150434245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    fCurrIndex = (fCurrIndex + 1) % fSamples.count();
15054605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this), (*fSamples[fCurrIndex])(),
1506db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     fTransitionNext));
150734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    return true;
15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
15098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1510501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.combool SampleWindow::goToSample(int i) {
1511501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    fCurrIndex = (i) % fSamples.count();
151248dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    this->loadView(create_transition(curr_view(this),(*fSamples[fCurrIndex])(), 6));
1513501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    return true;
1514501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1515501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1516501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.comSkString SampleWindow::getSampleTitle(int i) {
151748dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com    SkView* view = (*fSamples[i])();
1518501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    SkString title;
1519db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    SampleCode::RequestTitle(view, &title);
1520501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    view->unref();
1521501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    return title;
1522501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1523501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1524501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.comint SampleWindow::sampleCount() {
1525501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com    return fSamples.count();
1526501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com}
1527501775e5ac99f9805d1aba3aa7ca554a83d2dc43yangsu@google.com
1528db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleWindow::showOverview() {
15294605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    this->loadView(create_transition(curr_view(this),
15304605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com                                     create_overview(fSamples.count(), fSamples.begin()),
1531db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com                                     4));
1532db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
1533db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com
1534e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.comvoid SampleWindow::installDrawFilter(SkCanvas* canvas) {
1535e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com    canvas->setDrawFilter(new FlagsDrawFilter(fLCDState, fAAState,
1536e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com                                              fFilterState, fHintingState))->unref();
1537e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com}
1538e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com
15392c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::postAnimatingEvent() {
15402c8208f3a444098aee562f5a1ef620142807eda2Scroggo    if (fAnimating) {
154187fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com        (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATING_DELAY);
15422c8208f3a444098aee562f5a1ef620142807eda2Scroggo    }
15432c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
1544e23f194bf9747267b9dd42e238dfe217ed585c03reed@google.com
15458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onEvent(const SkEvent& evt) {
15462072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    if (evt.isType(gUpdateWindowTitleEvtName)) {
15472072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com        this->updateTitle();
15482072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com        return true;
15492072db89016c4e53a648f4d4cec08b1d6be8558creed@google.com    }
15508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (evt.isType(ANIMATING_EVENTTYPE)) {
15518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (fAnimating) {
15528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->nextSample();
15538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            this->postAnimatingEvent();
15548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
15558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
15568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1557ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (evt.isType("replace-transition-view")) {
1558ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->loadView((SkView*)SkEventSink::FindSink(evt.getFast32()));
1559db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
1560db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
156134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    if (evt.isType("set-curr-index")) {
1562db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->goToSample(evt.getFast32());
156334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        return true;
156434245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com    }
15652eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (isInvalEvent(evt)) {
15662eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        this->inval(NULL);
15672eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        return true;
15682eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
1569921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    int selected = -1;
1570ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindListIndex(evt, "Device Type", &selected)) {
1571921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->setDeviceType((DeviceType)selected);
15724605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com        return true;
1573921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1574b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (SkOSMenu::FindTriState(evt, "Pipe", &fPipeState)) {
1575ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com#ifdef PIPE_NET
1576b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (!fPipeState != SkOSMenu::kOnState)
1577ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            gServer.disconnectAll();
1578ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com#endif
1579b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        (void)SampleView::SetUsePipe(curr_view(this), fPipeState);
1580ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->updateTitle();
1581ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        this->inval(NULL);
1582921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1583921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
158467b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    if (SkOSMenu::FindTriState(evt, "Tiling", &fTilingState)) {
158567b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com        int nx = 1, ny = 1;
158667b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com        switch (fTilingState) {
158767b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com            case SkOSMenu::kOffState:   nx = 1; ny = 1; break;
158856b64a53318183ad528edeb1a26ade188ef63f7dreed@google.com            case SkOSMenu::kMixedState: nx = 1; ny = 16; break;
158956b64a53318183ad528edeb1a26ade188ef63f7dreed@google.com            case SkOSMenu::kOnState:    nx = 4; ny = 4; break;
159067b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com        }
159185cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        fTileCount.set(nx, ny);
159267b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com        this->inval(NULL);
159367b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com        return true;
159467b89eeeb07aa0485db233b5f356031fe15b57c4reed@google.com    }
1595ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Slide Show", NULL)) {
1596921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->toggleSlideshow();
1597921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1598921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1599ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindTriState(evt, "AA", &fAAState) ||
1600ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindTriState(evt, "LCD", &fLCDState) ||
1601ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindTriState(evt, "Filter", &fFilterState) ||
1602ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindTriState(evt, "Hinting", &fHintingState) ||
1603ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Clip", &fUseClip) ||
1604ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Zoomer", &fShowZoomer) ||
1605ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindSwitchState(evt, "Magnify", &fMagnify) ||
1606ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindListIndex(evt, "Transition-Next", &fTransitionNext) ||
1607ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkOSMenu::FindListIndex(evt, "Transition-Prev", &fTransitionPrev)) {
1608921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->inval(NULL);
1609921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->updateTitle();
1610921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1611921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1612ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Flip X", NULL)) {
1613921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        fFlipAxis ^= kFlipAxis_X;
1614f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
1615921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1616921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1617ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindSwitchState(evt, "Flip Y", NULL)) {
1618921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        fFlipAxis ^= kFlipAxis_Y;
1619f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com        this->updateMatrix();
1620921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
1621921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    }
1622ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com    if (SkOSMenu::FindAction(evt,"Save to PDF")) {
1623921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        this->saveToPdf();
1624921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com        return true;
16254605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onEvent(evt);
16278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1629f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.combool SampleWindow::onQuery(SkEvent* query) {
1630f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-count")) {
1631f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        query->setFast32(fSamples.count());
1632f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
1633f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1634f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("get-slide-title")) {
163548dd1a26ec07c5baa04856202e4e7e2a53e4d7e5bsalomon@google.com        SkView* view = (*fSamples[query->getFast32()])();
1636f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gTitleEvtName);
1637f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view->doQuery(&evt)) {
1638f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            query->setString("title", evt.findString(gTitleEvtName));
1639f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1640f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkSafeUnref(view);
1641f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return true;
1642f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
1643f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (query->isType("use-fast-text")) {
1644f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkEvent evt(gFastTextEvtName);
1645f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        return curr_view(this)->doQuery(&evt);
1646f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
164729038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    if (query->isType("ignore-window-bitmap")) {
164829038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        query->setFast32(this->getGrContext() != NULL);
164929038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        return true;
165029038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com    }
1651f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return this->INHERITED::onQuery(query);
1652f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
1653f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
165402939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#if 0 // UNUSED
16550ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.comstatic void cleanup_for_filename(SkString* name) {
16560ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    char* str = name->writable_str();
1657e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com    for (size_t i = 0; i < name->size(); i++) {
16580ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        switch (str[i]) {
16590ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ':': str[i] = '-'; break;
16600ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case '/': str[i] = '-'; break;
16610ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            case ' ': str[i] = '_'; break;
16620ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            default: break;
16630ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        }
16640ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    }
16650ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com}
166602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com#endif
16678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1668a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com//extern bool gIgnoreFastBlurRect;
1669a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com
16708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleChar(SkUnichar uni) {
1671f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
1672f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
1673f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
1674f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gCharEvtName);
1675f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(uni);
1676f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
1677f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
1678f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
1679f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1680f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
16814605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dx = 0xFF;
16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int dy = 0xFF;
16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (uni) {
16868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '5': dx =  0; dy =  0; break;
16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '8': dx =  0; dy = -1; break;
16888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '6': dx =  1; dy =  0; break;
16898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '2': dx =  0; dy =  1; break;
16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '4': dx = -1; dy =  0; break;
16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '7': dx = -1; dy = -1; break;
16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '9': dx =  1; dy = -1; break;
16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '3': dx =  1; dy =  1; break;
16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case '1': dx = -1; dy =  1; break;
16952e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
16978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
16988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
16992e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
17008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (0xFF != dx && 0xFF != dy) {
17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if ((dx | dy) == 0) {
17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX = fScrollTestY = 0;
17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestX += dx;
17058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            fScrollTestY += dy;
17068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
17078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->inval(NULL);
17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return true;
17098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17102e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
17110ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com    switch (uni) {
1712796763e0b2c06a7789185322561a1135e5484688djsollen@google.com        case 'b':
1713796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            {
1714796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            postEventToSink(SkNEW_ARGS(SkEvent, ("PictFileView::toggleBBox")), curr_view(this));
1715796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            this->updateTitle();
1716796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            this->inval(NULL);
1717796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            break;
1718796763e0b2c06a7789185322561a1135e5484688djsollen@google.com            }
1719a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com        case 'B':
1720a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com//            gIgnoreFastBlurRect = !gIgnoreFastBlurRect;
1721a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            this->inval(NULL);
1722a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            break;
1723a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com
1724ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        case 'f':
17254605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com            // only
17266ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com            toggleFPS();
1727ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            break;
1728f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        case 'g':
1729f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            fRequestGrabImage = true;
1730f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            this->inval(NULL);
1731a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            break;
1732a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com        case 'G':
1733a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            gShowGMBounds = !gShowGMBounds;
1734a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            postEventToSink(GMSampleView::NewShowSizeEvt(gShowGMBounds),
1735a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com                            curr_view(this));
1736a4f8137e67e31390b0e7edc5e637a3a02495d1a2reed@google.com            this->inval(NULL);
1737f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
17382eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        case 'i':
17392eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->zoomIn();
17402eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            break;
174108526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo        case 'o':
174208526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo            this->zoomOut();
174308526c07f4f530e56b70d4b22f5a4af35d9ebccascroggo            break;
17442eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        case 'r':
17452eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            fRotate = !fRotate;
17462eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->inval(NULL);
17472eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->updateTitle();
17482eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            return true;
1749e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        case 'k':
1750e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            fPerspAnim = !fPerspAnim;
1751e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            this->inval(NULL);
1752e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            this->updateTitle();
1753e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com            return true;
1754cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
175574913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com        case '\\':
1756b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->setDeviceType(kNullGPU_DeviceType);
1757b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->inval(NULL);
1758b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com            this->updateTitle();
175974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com            return true;
176005e70247c31ae927074ef27ea9893634a8dda543twiz@google.com        case 'p':
176105e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            {
176205e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                GrContext* grContext = this->getGrContext();
176305e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                if (grContext) {
176405e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                    size_t cacheBytes = grContext->getGpuTextureCacheBytes();
176505e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                    grContext->freeGpuResources();
176605e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                    SkDebugf("Purged %d bytes from the GPU resource cache.\n",
176705e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                             cacheBytes);
176805e70247c31ae927074ef27ea9893634a8dda543twiz@google.com                }
176905e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            }
177005e70247c31ae927074ef27ea9893634a8dda543twiz@google.com            return true;
1771cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
17722eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        case 's':
17732eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            fScale = !fScale;
17742eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->inval(NULL);
17752eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            this->updateTitle();
17762eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org            return true;
17770ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com        default:
17780ae6b245f2b79bc04f0801b08fcf05abcf98fd6creed@android.com            break;
17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17804605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
17817dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    if (fAppMenu->handleKeyEquivalent(uni)|| fSlideMenu->handleKeyEquivalent(uni)) {
17827dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com        this->onUpdateMenu(fAppMenu);
17837dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com        this->onUpdateMenu(fSlideMenu);
1784db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return true;
1785db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    }
17868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleChar(uni);
17878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
17888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1789921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.comvoid SampleWindow::setDeviceType(DeviceType type) {
1790b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    if (type == fDeviceType)
1791b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com        return;
1792b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1793b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDevManager->tearDownBackend(this);
1794b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1795b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    fDeviceType = type;
1796b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
17971195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    fDevManager->setUpBackend(this, fMSAASampleCount);
1798b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com
1799921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    this->updateTitle();
1800921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    this->inval(NULL);
1801921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com}
1802921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com
18032c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::toggleSlideshow() {
18042c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fAnimating = !fAnimating;
18052c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->postAnimatingEvent();
18062c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->updateTitle();
18072c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
18082c8208f3a444098aee562f5a1ef620142807eda2Scroggo
18092c8208f3a444098aee562f5a1ef620142807eda2Scroggovoid SampleWindow::toggleRendering() {
1810b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    this->setDeviceType(cycle_devicetype(fDeviceType));
18112c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->updateTitle();
18122c8208f3a444098aee562f5a1ef620142807eda2Scroggo    this->inval(NULL);
18132c8208f3a444098aee562f5a1ef620142807eda2Scroggo}
18142c8208f3a444098aee562f5a1ef620142807eda2Scroggo
18156ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.comvoid SampleWindow::toggleFPS() {
18166ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    fMeasureFPS = !fMeasureFPS;
18176ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    this->updateTitle();
18186ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com    this->inval(NULL);
18196ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com}
18206ff82553df07ec9502bfe5b4a97a2c2aaf15e39fdjsollen@google.com
18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDumpCanvas.h"
18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SampleWindow::onHandleKey(SkKey key) {
1824f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    {
1825f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkView* view = curr_view(this);
1826f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (view) {
1827f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            SkEvent evt(gKeyEvtName);
1828f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            evt.setFast32(key);
1829f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (view->doQuery(&evt)) {
1830f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                return true;
1831f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
1832f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
1833f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    switch (key) {
18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kRight_SkKey:
18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            if (this->nextSample()) {
18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                return true;
18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kLeft_SkKey:
1841e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com            if (this->previousSample()) {
1842e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com                return true;
1843e2dd973e4b0dac58610b73d577e91899c2b1c4eascroggo@google.com            }
18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kUp_SkKey:
1846dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if (USE_ARROWS_FOR_ZOOM) {
1847e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->changeZoomLevel(1.f);
1848dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            } else {
1849dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                fNClip = !fNClip;
1850dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                this->inval(NULL);
1851e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->updateTitle();
1852dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        case kDown_SkKey:
1855dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            if (USE_ARROWS_FOR_ZOOM) {
1856e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->changeZoomLevel(-1.f);
1857dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            } else {
1858dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org                this->setConfig(cycle_configs(this->getBitmap().config()));
1859e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com                this->updateTitle();
1860dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org            }
18618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18626f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        case kOK_SkKey: {
18636f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            SkString title;
18646f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org            if (curr_title(this, &title)) {
18656f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org                writeTitleToPrefs(title.c_str());
18668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            }
18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return true;
18686f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org        }
186934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com        case kBack_SkKey:
1870db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com            this->showOverview();
187134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com            return true;
18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        default:
18738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            break;
18748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return this->INHERITED::onHandleKey(key);
18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
187852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com///////////////////////////////////////////////////////////////////////////////
187952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
188052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.comstatic const char gGestureClickType[] = "GestureClickType";
188152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
1882d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggobool SampleWindow::onDispatchClick(int x, int y, Click::State state,
18834d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        void* owner, unsigned modi) {
18840f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    if (Click::kMoved_State == state) {
18850f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo        updatePointer(x, y);
18860f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo    }
1887dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    int w = SkScalarRound(this->width());
1888dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    int h = SkScalarRound(this->height());
1889dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
1890dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    // check for the resize-box
1891dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (w - x < 16 && h - y < 16) {
1892dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org        return false;   // let the OS handle the click
18934605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com    }
1894db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    else if (fMagnify) {
1895db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        //it's only necessary to update the drawing if there's a click
1896db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->inval(NULL);
1897db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        return false; //prevent dragging while magnify is enabled
18984d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    } else {
18994d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        // capture control+option, and trigger debugger
19004d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        if ((modi & kControl_SkModifierKey) && (modi & kOption_SkModifierKey)) {
19014d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            if (Click::kDown_State == state) {
19024d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                SkEvent evt("debug-hit-test");
19034d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                evt.setS32("debug-hit-test-x", x);
19044d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                evt.setS32("debug-hit-test-y", y);
19054d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                curr_view(this)->doEvent(evt);
19064d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            }
19074d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            return true;
19084d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        } else {
19094d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            return this->INHERITED::onDispatchClick(x, y, state, owner, modi);
19104d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        }
1911dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
1912dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org}
1913dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
191452f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.comclass GestureClick : public SkView::Click {
191552f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.compublic:
191652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    GestureClick(SkView* target) : SkView::Click(target) {
191752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        this->setType(gGestureClickType);
191852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
191952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
192052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    static bool IsGesture(Click* click) {
192152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        return click->isType(gGestureClickType);
192252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
192352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com};
192452f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
19254d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comSkView::Click* SampleWindow::onFindClickHandler(SkScalar x, SkScalar y,
19264d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com                                                unsigned modi) {
192752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    return new GestureClick(this);
192852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com}
192952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
193052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.combool SampleWindow::onClick(Click* click) {
193152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    if (GestureClick::IsGesture(click)) {
19324d4f281b28c3db0513ea1a68db4577e2518002b3bsalomon@google.com        float x = static_cast<float>(click->fICurr.fX);
19334d4f281b28c3db0513ea1a68db4577e2518002b3bsalomon@google.com        float y = static_cast<float>(click->fICurr.fY);
19344605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
193552f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        switch (click->fState) {
193652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kDown_State:
1937d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchBegin(click->fOwner, x, y);
193852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
193952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kMoved_State:
1940d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchMoved(click->fOwner, x, y);
1941f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com                this->updateMatrix();
194252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
194352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com            case SkView::Click::kUp_State:
1944d3aed39ab1ad88b05b9423ee1329c227d1f8f612Scroggo                fGesture.touchEnd(click->fOwner);
1945f03bb566e25ace918f8fdda3cb8426626a00894creed@google.com                this->updateMatrix();
194652f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com                break;
194752f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        }
194852f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com        return true;
194952f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    }
195052f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com    return false;
195152f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com}
195252f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
195352f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com///////////////////////////////////////////////////////////////////////////////
195452f57e1d11a00bdc5efb96709446546cdbc1ff9dreed@google.com
19558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::loadView(SkView* view) {
19568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* prev = iter.next();
19588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (prev) {
19598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        prev->detachFromParent();
19608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
19614605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
19628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setVisibleP(true);
1963f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    view->setClipToBounds(false);
19648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->attachChildToFront(view)->unref();
19658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
19668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1967921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    //repopulate the slide menu when a view is loaded
19687dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    fSlideMenu->reset();
1969388974f1dd4d7f1a202aac8a007dc2a4eaf051cbdjsollen@google.com
1970b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    (void)SampleView::SetUsePipe(view, fPipeState);
1971921091f29e2ecfec55f4d1ac5611b4aa4731e7d6yangsu@google.com    if (SampleView::IsSampleView(view))
19727dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com        ((SampleView*)view)->requestMenu(fSlideMenu);
19737dadc748d96fdf6c1eadc960f1481807d2ac90cfscroggo@google.com    this->onUpdateMenu(fSlideMenu);
19748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();
19758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
19768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* gConfigNames[] = {
19788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "unknown config",
19798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "A1",
19808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "A8",
19818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "Index8",
19828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "565",
19838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "4444",
19848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "8888"
19858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
19868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const char* configToString(SkBitmap::Config c) {
19888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return gConfigNames[c];
19898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
19908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1991098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.comstatic const char* gDeviceTypePrefix[] = {
19928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "raster: ",
19938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "picture: ",
1994cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
199574913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com    "opengl: ",
1996b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com#if SK_ANGLE
1997b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.com    "angle: ",
1998cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
199974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com    "null-gl: "
2000cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2002cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comSK_COMPILE_ASSERT(SK_ARRAY_COUNT(gDeviceTypePrefix) == SampleWindow::kDeviceTypeCnt,
2003cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com                  array_size_mismatch);
20048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2005db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic const char* trystate_str(SkOSMenu::TriState state,
2006569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com                                const char trueStr[], const char falseStr[]) {
2007db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    if (SkOSMenu::kOnState == state) {
2008569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        return trueStr;
2009db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    } else if (SkOSMenu::kOffState == state) {
2010569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com        return falseStr;
2011569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    }
2012569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    return NULL;
2013569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com}
2014569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
20158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::updateTitle() {
20166f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkView* view = curr_view(this);
20178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20186f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    SkString title;
20196f6e8c39a7b07f8a916a60ad27f17bd13f3c89admike@reedtribe.org    if (!curr_title(this, &title)) {
20208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.set("<unknown>");
20218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
20222e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2023098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    title.prepend(gDeviceTypePrefix[fDeviceType]);
20248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(" ");
20268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    title.prepend(configToString(this->getBitmap().config()));
20272e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
20288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fAnimating) {
20298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        title.prepend("<A> ");
20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
20316c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fScale) {
20326c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        title.prepend("<S> ");
20336c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
20346c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    if (fRotate) {
20356c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com        title.prepend("<R> ");
20366c5f6f25b43f1210decb48956c1a2fbe5b58f889reed@android.com    }
2037e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    if (fNClip) {
2038e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com        title.prepend("<C> ");
2039e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    }
2040e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    if (fPerspAnim) {
2041e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com        title.prepend("<K> ");
2042e8f091093509d946a7f6722b40033a3dc946dc0fbsalomon@google.com    }
2043569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com
2044569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(trystate_str(fLCDState, "LCD ", "lcd "));
2045569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(trystate_str(fAAState, "AA ", "aa "));
204609e3baaaf54a8a3c701cfc5ad24a8180464a4742reed@google.com    title.prepend(trystate_str(fFilterState, "H ", "h "));
2047569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(fFlipAxis & kFlipAxis_X ? "X " : NULL);
2048569e0435af62bdb88a662fa0592f75673a17afd9reed@google.com    title.prepend(fFlipAxis & kFlipAxis_Y ? "Y " : NULL);
2049dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org
2050dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    if (fZoomLevel) {
2051e32b5837c3f35b80502759f3de3e8cadf6625f4edjsollen@google.com        title.prependf("{%.2f} ", SkScalarToFloat(fZoomLevel));
2052dd0cd34067d103ace7c6739405cb7885d8ad3fb2mike@reedtribe.org    }
20534605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
20542eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (fMeasureFPS) {
205543e10145911bde6ac8c3f14fd46611a13c76f8b9reed@google.com        title.appendf(" %8.3f ms", fMeasureFPS_Time / (float)FPS_REPEAT_COUNT);
20562eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
2057a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    if (SampleView::IsSampleView(view)) {
2058b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        switch (fPipeState) {
2059b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            case SkOSMenu::kOnState:
2060b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                title.prepend("<Pipe> ");
2061b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
2062b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            case SkOSMenu::kMixedState:
2063b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                title.prepend("<Tiled Pipe> ");
2064b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
20654605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2066b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            default:
2067b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                break;
2068b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2069a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com        title.prepend("! ");
2070a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    }
20712eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2072cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
207382502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com    if (IsGpuDeviceType(fDeviceType) &&
20744750fa55f27e43770e7f5f3161ebdbac42e0da8arobertphillips@google.com        NULL != fDevManager &&
207582502e2e3966a9b0e48665f20154eaacd2a452b3bsalomon@google.com        fDevManager->getGrRenderTarget() &&
20761195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        fDevManager->getGrRenderTarget()->numSamples() > 0) {
20771195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com        title.appendf(" [MSAA: %d]",
20781195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com                       fDevManager->getGrRenderTarget()->numSamples());
20791195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com    }
2080cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
20811195925b05ee9d666ea8a8f68fde5d8ca7e49b04bsalomon@google.com
20828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->setTitle(title.c_str());
20838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
20848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SampleWindow::onSizeChange() {
20868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->INHERITED::onSizeChange();
20874605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
20888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView::F2BIter iter(this);
20898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkView* view = iter.next();
20908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    view->setSize(this->width(), this->height());
20912e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
20928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // rebuild our clippath
20938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
20948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar W = this->width();
20958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkScalar H = this->height();
20962e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
20978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.reset();
20988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0
20998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
21008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            SkRect r;
21018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            r.set(SK_Scalar1, y, SkIntToScalar(30), y + SkIntToScalar(30));
21028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            for (; r.fLeft < W; r.offset(SkIntToScalar(32), 0))
21038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fClipPath.addRect(r);
21048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
21058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
21068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRect r;
21078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(0, 0, W, H);
21088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCCW_Direction);
21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        r.set(W/4, H/4, W*3/4, H*3/4);
21108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fClipPath.addRect(r, SkPath::kCW_Direction);
21118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
21128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
21132e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
21142c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterX = SkScalarHalf(this->width());
21152c8208f3a444098aee562f5a1ef620142807eda2Scroggo    fZoomCenterY = SkScalarHalf(this->height());
21162c8208f3a444098aee562f5a1ef620142807eda2Scroggo
211756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
2118b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // FIXME: The first draw after a size change does not work on Android, so
2119b4490c7435df46261c00dbfdcdd9d2e9d56d1f52Scroggo    // we post an invalidate.
212062b65b0913566381db468277de07e5dd2a9237caScroggo    this->postInvalDelay();
2121716a0387ca197ca728ba691f3d812d4252c0f10bScroggo#endif
21228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->updateTitle();    // to refresh our config
2123098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    fDevManager->windowSizeChanged(this);
21248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
21258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
21268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
21278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2128a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.comstatic const char is_sample_view_tag[] = "sample-is-sample-view";
21292eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgstatic const char repeat_count_tag[] = "sample-set-repeat-count";
21300faac1e8579088a39f38d02ff675f14d7deb608dreed@google.comstatic const char set_use_pipe_tag[] = "sample-set-use-pipe";
21312eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2132a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.combool SampleView::IsSampleView(SkView* view) {
2133a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    SkEvent evt(is_sample_view_tag);
2134a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    return view->doQuery(&evt);
2135a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com}
2136a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com
2137f21833999d90ad9c8c584cff3238797b39cfc00breed@google.combool SampleView::SetRepeatDraw(SkView* view, int count) {
21382eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    SkEvent evt(repeat_count_tag);
21392eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    evt.setFast32(count);
2140f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    return view->doEvent(evt);
21412eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21422eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2143b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.combool SampleView::SetUsePipe(SkView* view, SkOSMenu::TriState state) {
2144b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    SkEvent evt;
2145b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    evt.setS32(set_use_pipe_tag, state);
21460faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    return view->doEvent(evt);
21470faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com}
21480faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com
21492eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgbool SampleView::onEvent(const SkEvent& evt) {
21502eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    if (evt.isType(repeat_count_tag)) {
21512eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        fRepeatCount = evt.getFast32();
21522eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org        return true;
21532eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
21544d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
2155b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    int32_t pipeHolder;
2156b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (evt.findS32(set_use_pipe_tag, &pipeHolder)) {
2157b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fPipeState = static_cast<SkOSMenu::TriState>(pipeHolder);
21580faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com        return true;
21590faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
21604d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
21614d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    if (evt.isType("debug-hit-test")) {
21624d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        fDebugHitTest = true;
21634d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        evt.findS32("debug-hit-test-x", &fDebugHitTestLoc.fX);
21644d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        evt.findS32("debug-hit-test-y", &fDebugHitTestLoc.fY);
21654d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        this->inval(NULL);
21664d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return true;
21674d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    }
21684d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
21692eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return this->INHERITED::onEvent(evt);
21702eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21712eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
21722eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgbool SampleView::onQuery(SkEvent* evt) {
2173a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    if (evt->isType(is_sample_view_tag)) {
2174a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com        return true;
2175a6ff4dc22d5006dc588769aa20c8b0bb4fde6d43reed@google.com    }
21762eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    return this->INHERITED::onQuery(evt);
21772eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
21782eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
217964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
218064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comclass SimplePC : public SkGPipeController {
218164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.compublic:
218264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SimplePC(SkCanvas* target);
218364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    ~SimplePC();
21844605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
218564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    virtual void* requestBlock(size_t minRequest, size_t* actual);
218664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    virtual void notifyWritten(size_t bytes);
218764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
218864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comprivate:
2189961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    SkGPipeReader   fReader;
2190961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    void*           fBlock;
2191961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    size_t          fBlockSize;
2192961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    size_t          fBytesWritten;
2193961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    int             fAtomsWritten;
219464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkGPipeReader::Status   fStatus;
219564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
219664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    size_t        fTotalWritten;
219764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com};
219864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
219964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comSimplePC::SimplePC(SkCanvas* target) : fReader(target) {
220064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlock = NULL;
220164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlockSize = fBytesWritten = 0;
220264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fStatus = SkGPipeReader::kDone_Status;
220364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fTotalWritten = 0;
2204961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    fAtomsWritten = 0;
220564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
220664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
220764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comSimplePC::~SimplePC() {
220864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com//    SkASSERT(SkGPipeReader::kDone_Status == fStatus);
22090faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    if (fTotalWritten) {
2210b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten,
2211b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                 fAtomsWritten, fStatus);
2212db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef  PIPE_FILE
2213b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        //File is open in append mode
2214b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        FILE* f = fopen(FILE_PATH, "ab");
2215b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkASSERT(f != NULL);
2216b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f);
2217b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        fclose(f);
2218db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
2219db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#ifdef PIPE_NET
2220b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (fAtomsWritten > 1 && fTotalWritten > 4) { //ignore done
2221b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            gServer.acceptConnections();
2222b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            gServer.writePacket(fBlock, fTotalWritten);
2223b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2224db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#endif
22250faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
2226db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com    sk_free(fBlock);
222764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
222864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
222964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comvoid* SimplePC::requestBlock(size_t minRequest, size_t* actual) {
223064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    sk_free(fBlock);
223164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
223264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlockSize = minRequest * 4;
223364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBlock = sk_malloc_throw(fBlockSize);
223464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBytesWritten = 0;
223564e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    *actual = fBlockSize;
223664e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    return fBlock;
223764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
223864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
223964e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.comvoid SimplePC::notifyWritten(size_t bytes) {
224064e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkASSERT(fBytesWritten + bytes <= fBlockSize);
224164e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes);
224264e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    SkASSERT(SkGPipeReader::kError_Status != fStatus);
224364e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fBytesWritten += bytes;
224464e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com    fTotalWritten += bytes;
22454605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2246961ddb04a0a7aba843032d829ab867518e52559ereed@google.com    fAtomsWritten += 1;
224764e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com}
224864e3eb24e52a84613ff8c1da5dac6f4b5ba38320reed@google.com
2249db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleView::draw(SkCanvas* canvas) {
2250b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    if (SkOSMenu::kOffState == fPipeState) {
2251b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        this->INHERITED::draw(canvas);
2252b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com    } else {
2253db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        SkGPipeWriter writer;
2254db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        SimplePC controller(canvas);
2255b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        TiledPipeController tc(canvas->getDevice()->accessBitmap(false),
2256b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com                               &canvas->getTotalMatrix());
2257b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        SkGPipeController* pc;
2258b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        if (SkOSMenu::kMixedState == fPipeState) {
2259b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            pc = &tc;
2260b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        } else {
2261b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com            pc = &controller;
2262b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        }
2263dde0956375e87027df2fdd80d430dd819c217aacreed@google.com        uint32_t flags = SkGPipeWriter::kCrossProcess_Flag;
22644605a3f3ff8fa2072f98e6bcb71bc43d4c6196d6chudy@google.com
2265b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com        canvas = writer.startRecording(pc, flags);
2266db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        //Must draw before controller goes out of scope and sends data
2267db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com        this->INHERITED::draw(canvas);
2268ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        //explicitly end recording to ensure writer is flushed before the memory
2269ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        //is freed in the deconstructor of the controller
2270ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        writer.endRecording();
22710faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com    }
2272db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}
22734d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
22744d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com#include "SkBounder.h"
22754d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
22764d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comclass DebugHitTestBounder : public SkBounder {
22774d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.compublic:
22784d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    DebugHitTestBounder(int x, int y) {
22794d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        fLoc.set(x, y);
22804d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    }
22814d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
22824d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    virtual bool onIRect(const SkIRect& bounds) SK_OVERRIDE {
22834d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        if (bounds.contains(fLoc.x(), fLoc.y())) {
22844d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            //
22854d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            // Set a break-point here to see what was being drawn under
22864d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            // the click point (just needed a line of code to stop the debugger)
22874d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            //
22884d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com            bounds.centerX();
22894d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        }
22904d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        return true;
22914d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    }
22924d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
22934d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.comprivate:
22944d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    SkIPoint fLoc;
22954d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    typedef SkBounder INHERITED;
22964d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com};
22974d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
2298db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comvoid SampleView::onDraw(SkCanvas* canvas) {
229981e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com    this->onDrawBackground(canvas);
230081e3d7f7943d5c257a07580b75218a5e256b0aadreed@google.com
23014d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    DebugHitTestBounder bounder(fDebugHitTestLoc.x(), fDebugHitTestLoc.y());
23024d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    if (fDebugHitTest) {
23034d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com        canvas->setBounder(&bounder);
23044d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    }
23054d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
23062eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    for (int i = 0; i < fRepeatCount; i++) {
230785cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        SkAutoCanvasRestore acr(canvas, true);
230885cade0a10217a50aebb495099ecc0435fe08b23scroggo@google.com        this->onDrawContent(canvas);
23092eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org    }
23104d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com
23114d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    fDebugHitTest = false;
23124d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com    canvas->setBounder(NULL);
23132eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
23142eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
23152eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.orgvoid SampleView::onDrawBackground(SkCanvas* canvas) {
2316f21833999d90ad9c8c584cff3238797b39cfc00breed@google.com    canvas->drawColor(fBGColor);
23172eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org}
23182eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
23192eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org///////////////////////////////////////////////////////////////////////////////
23202eb595292b9624371d1698ae9da7accb4c09c26cmike@reedtribe.org
2321f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comtemplate <typename T> void SkTBSort(T array[], int count) {
2322f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 1; i < count - 1; i++) {
2323f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        bool didSwap = false;
2324f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = count - 1; j > i; --j) {
2325f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            if (array[j] < array[j-1]) {
2326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                T tmp(array[j-1]);
2327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j-1] = array[j];
2328f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                array[j] = tmp;
2329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com                didSwap = true;
2330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            }
2331f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2332f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (!didSwap) {
2333f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            break;
2334f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2335f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
23362e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2337f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int k = 0; k < count - 1; k++) {
2338f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkASSERT(!(array[k+1] < array[k]));
2339f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2340f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2341f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2342f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include "SkRandom.h"
2343f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2344f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void rand_rect(SkIRect* rect, SkRandom& rand) {
2345f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int bits = 8;
2346f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    int shift = 32 - bits;
2347f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
2348f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com              rand.nextU() >> shift, rand.nextU() >> shift);
2349f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rect->sort();
2350f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2351f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2352f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void dumpRect(const SkIRect& r) {
2353f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf(" { %d, %d, %d, %d },\n",
2354f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fLeft, r.fTop,
2355f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com             r.fRight, r.fBottom);
2356f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2357f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2358f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test_rects(const SkIRect rect[], int count) {
2359f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRegion rgn0, rgn1;
2360f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2361f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (int i = 0; i < count; i++) {
2362f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        rgn0.op(rect[i], SkRegion::kUnion_Op);
2363f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com     //   dumpRect(rect[i]);
2364f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2365f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    rgn1.setRects(rect, count);
2366f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2367f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (rgn0 != rgn1) {
2368f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
2369f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int i = 0; i < count; i++) {
2370f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            dumpRect(rect[i]);
2371f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2372f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkDebugf("\n");
2373f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2374f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2375f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2376f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic void test() {
2377f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    size_t i;
2378f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2379f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r0[] = {
2380f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 1 },
2381f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 2, 3, 3 },
2382f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2383f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r1[] = {
2384f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 3 },
2385f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 1, 1, 2, 2 },
2386f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 0, 3, 3 },
2387f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2388f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const SkIRect r2[] = {
2389f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 0, 0, 1, 2 },
2390f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 2, 1, 3, 3 },
2391f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 4, 0, 5, 1 },
2392f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { 6, 0, 7, 4 },
2393f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2394f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2395f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const struct {
2396f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const SkIRect* fRects;
2397f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        int            fCount;
2398f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    } gRecs[] = {
2399f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r0, SK_ARRAY_COUNT(r0) },
2400f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r1, SK_ARRAY_COUNT(r1) },
2401f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        { r2, SK_ARRAY_COUNT(r2) },
2402f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
2403f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2404f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
2405f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(gRecs[i].fRects, gRecs[i].fCount);
2406f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
24072e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com
2408f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkRandom rand;
2409f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    for (i = 0; i < 10000; i++) {
2410f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkRegion rgn0, rgn1;
2411f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
2412f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        const int N = 8;
2413f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        SkIRect rect[N];
2414f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        for (int j = 0; j < N; j++) {
2415f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            rand_rect(&rect[j], rand);
2416f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
2417f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        test_rects(rect, N);
2418f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
2419f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
2420f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
242102939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
242202939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comSkOSWindow* create_sk_window(void* hwnd, int argc, char** argv);
242378b8253c0a389a484e15439722e35a1658eb3b01senorblanco@chromium.orgSkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
242402939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    if (false) { // avoid bit rot, suppress warning
242502939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com        test();
242602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com    }
2427098e96df6ab0327f18537c7006ff2b0b4116ee30bsalomon@google.com    return new SampleWindow(hwnd, argc, argv, NULL);
24288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
24298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
243002939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
243102939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid get_preferred_size(int* x, int* y, int* width, int* height);
24328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid get_preferred_size(int* x, int* y, int* width, int* height) {
24338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *x = 10;
24348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *y = 50;
24358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *width = 640;
24368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *height = 480;
24378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
24388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
24395987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#ifdef SK_BUILD_FOR_IOS
24405987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comvoid save_args(int argc, char *argv[]) {
24415987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
24425987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
24435987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
244402939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
244502939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid application_init();
24468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_init() {
24478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    setenv("ANDROID_ROOT", "../../../data", 0);
2448e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#ifdef SK_BUILD_FOR_MAC
24498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    setenv("ANDROID_ROOT", "/android/device/data", 0);
2450e191b16fda2f5afea3a90653c1cd4f5a3c436e89reed@android.com#endif
24512fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Init();
24522fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Init();
24538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
24548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
245502939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.com// FIXME: this should be in a header
245602939ce4bddd3223d9e8cc98d4abd02939b7f70acaryclark@google.comvoid application_term();
24578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid application_term() {
24582fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkEvent::Term();
24592fbc7fa460c99bffa78b9afb9aaa4dc0db68e1babsalomon@google.com    SkGraphics::Term();
24608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2461