11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
80b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SampleCode.h"
90b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkCanvas.h"
100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkPaint.h"
110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkView.h"
120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkLayer.h"
130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#include "SkMatrix44.h"
150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test_inv(const char label[], const SkMatrix44& mat) {
160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDebugf("%s\n", label);
170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    mat.dump();
180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMatrix44 inv;
200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (mat.invert(&inv)) {
210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        inv.dump();
220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    } else {
230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkDebugf("--- invert failed\n");
240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMatrix44 a, b;
270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    a.setConcat(mat, inv);
280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    b.setConcat(inv, mat);
290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDebugf("concat mat with inverse pre=%d post=%d\n", a.isIdentity(), b.isIdentity());
300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!a.isIdentity()) {
310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        a.dump();
320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (!b.isIdentity()) {
340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        b.dump();
350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDebugf("\n");
370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test_map(SkScalar x0, SkScalar y0, SkScalar z0,
400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                     const SkMatrix44& mat,
410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                     SkScalar x1, SkScalar y1, SkScalar z1) {
420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkVector4 src, dst;
430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    src.set(x0, y0, z0);
440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    dst = mat * src;
450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDebugf("map: src: %g %g %g dst: %g %g %g (%g) expected: %g %g %g match: %d\n",
460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             x0, y0, z0,
470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             dst.fData[0], dst.fData[1], dst.fData[2], dst.fData[3],
480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             x1, y1, z1,
490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             dst.fData[0] == x1 && dst.fData[1] == y1 && dst.fData[2] == z1);
500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test_33(const SkMatrix44& mat,
530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                    SkScalar x0, SkScalar x1, SkScalar x2,
540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                    SkScalar y0, SkScalar y1, SkScalar y2) {
550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMatrix dst = mat;
560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (dst[0] != x0 || dst[1] != x1 || dst[2] != x2 ||
570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        dst[3] != y0 || dst[4] != y1 || dst[5] != y2) {
580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkString str;
590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        dst.toDumpString(&str);
600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkDebugf("3x3: expected 3x3 [%g %g %g] [%g %g %g] bug got %s\n",
610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                 x0, x1, x2, y0, y1, y2, str.c_str());
620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void test44() {
660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMatrix44 m0, m1, m2;
670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("identity", m0);
690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setTranslate(2,3,4);
700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("translate", m0);
710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setScale(2,3,4);
720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("scale", m0);
730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.postTranslate(5, 6, 7);
740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("postTranslate", m0);
750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setScale(2,3,4);
760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m1.setTranslate(5, 6, 7);
770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setConcat(m0, m1);
780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("postTranslate2", m0);
790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setScale(2,3,4);
800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.preTranslate(5, 6, 7);
810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("preTranslate", m0);
820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setScale(2, 4, 6);
840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.postScale(SkDoubleToMScalar(0.5));
850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_inv("scale/postscale to 1,2,3", m0);
860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.reset();
880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(1, 0, 0, m0, 1, 0, 0);
890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 1, 0, m0, 0, 1, 0);
900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 0, 1, m0, 0, 0, 1);
910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setScale(2, 3, 4);
920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(1, 0, 0, m0, 2, 0, 0);
930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 1, 0, m0, 0, 3, 0);
940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 0, 1, m0, 0, 0, 4);
950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setTranslate(2, 3, 4);
960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 0, 0, m0, 2, 3, 4);
970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.preScale(5, 6, 7);
980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(1, 0, 0, m0, 7, 3, 4);
990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 1, 0, m0, 2, 9, 4);
1000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(0, 0, 1, m0, 2, 3, 11);
1010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMScalar deg = 45;
1030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setRotateDegreesAbout(0, 0, 1, deg);
1040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_map(1, 0, 0, m0, 0.707106769, -0.707106769, 0);
1050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.reset();
1070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_33(m0, 1, 0, 0, 0, 1, 0);
1080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    m0.setTranslate(3, 4, 5);
1090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    test_33(m0, 1, 0, 3, 0, 1, 4);
1100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
1110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
1130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic void dump_layers(const SkLayer* layer, int tab = 0) {
1150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkMatrix matrix;
1160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkString matrixStr;
1170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    layer->getLocalTransform(&matrix);
1190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    matrix.toDumpString(&matrixStr);
1200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    for (int j = 0; j < tab; j++) {
1220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkDebugf(" ");
1230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkDebugf("layer=%p parent=%p size=[%g %g] transform=%s\n",
1250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             layer, layer->getParent(), layer->getWidth(), layer->getHeight(),
1260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger             matrixStr.c_str());
1270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    for (int i = 0; i < layer->countChildren(); i++) {
1280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        dump_layers(layer->getChild(i), tab + 4);
1290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger}
1310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass TestLayer : public SkLayer {
1330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic:
1340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    TestLayer(SkColor c) : fColor(c) {}
1350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected:
1370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void onDraw(SkCanvas* canvas, SkScalar opacity) {
1380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkRect r;
1390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        r.set(0, 0, this->getWidth(), this->getHeight());
1400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkPaint paint;
1420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint.setColor(fColor);
1430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        paint.setAlpha(SkScalarRound(opacity * 255));
1440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->drawRect(r, paint);
1460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
1470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate:
1490b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkColor fColor;
1500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger};
1510b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1520b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerclass SkLayerView : public SkView {
1530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate:
1540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkLayer* fRootLayer;
1550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkLayer* fLastChild;
1560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerpublic:
1570b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger	SkLayerView() {
1580b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        test44();
1590b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        static const int W = 600;
1600b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        static const int H = 440;
1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        static const struct {
1620b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            int fWidth;
1630b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            int fHeight;
1640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkColor fColor;
1650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            int fPosX;
1660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            int fPosY;
1670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        } gData[] = {
1680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            { 120, 80, SK_ColorRED, 0, 0 },
1690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            { 120, 80, SK_ColorGREEN, W - 120, 0 },
1700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            { 120, 80, SK_ColorBLUE, 0, H - 80 },
1710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            { 120, 80, SK_ColorMAGENTA, W - 120, H - 80 },
1720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        };
1730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fRootLayer = new TestLayer(0xFFDDDDDD);
1750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fRootLayer->setSize(W, H);
1760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
1770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkLayer* child = new TestLayer(gData[i].fColor);
1780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            child->setSize(gData[i].fWidth, gData[i].fHeight);
1790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            child->setPosition(gData[i].fPosX, gData[i].fPosY);
1800b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fRootLayer->addChild(child)->unref();
1810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
1820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkLayer* child = new TestLayer(0xFFDD8844);
1840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        child->setSize(120, 80);
1850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        child->setPosition(fRootLayer->getWidth()/2 - child->getWidth()/2,
1860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                           fRootLayer->getHeight()/2 - child->getHeight()/2);
1870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        child->setAnchorPoint(SK_ScalarHalf, SK_ScalarHalf);
1880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        {
1890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkMatrix m;
1900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            m.setRotate(SkIntToScalar(30));
1910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            child->setMatrix(m);
1920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
1930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fLastChild = child;
1940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fRootLayer->addChild(child)->unref();
1950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
1960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (false) {
1970b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkMatrix matrix;
1980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            matrix.setScale(0.5, 0.5);
1990b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fRootLayer->setMatrix(matrix);
2000b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2020b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger//        dump_layers(fRootLayer);
2030b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2050b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual ~SkLayerView() {
2060b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkSafeUnref(fRootLayer);
2070b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2080b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2090b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprotected:
2100b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    // overrides from SkEventSink
2110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual bool onQuery(SkEvent* evt) {
2120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (SampleCode::TitleQ(*evt)) {
2130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SampleCode::TitleR(evt, "SkLayer");
2140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            return true;
2150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        return this->INHERITED::onQuery(evt);
2170b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2190b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    virtual void onDraw(SkCanvas* canvas) {
2200b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->drawColor(SK_ColorWHITE);
2210b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        canvas->translate(20, 20);
2230b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        fRootLayer->draw(canvas);
2240b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2250b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        // visual test of getLocalTransform
2260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (true) {
2270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkMatrix matrix;
2280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            fLastChild->localToGlobal(&matrix);
2290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            SkPaint paint;
2300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setStyle(SkPaint::kStroke_Style);
2310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setStrokeWidth(5);
2320b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            paint.setColor(0x88FF0000);
2330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->concat(matrix);
2340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            canvas->drawRect(SkRect::MakeSize(fLastChild->getSize()), paint);
2350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
2360b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
2370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerprivate:
2390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    typedef SkView INHERITED;
2400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger};
2410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
2430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
2440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkView* MyFactory() { return new SkLayerView; }
2450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenbergerstatic SkViewRegister reg(MyFactory);
2460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
247