Home | History | Annotate | Download | only in samplecode
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "SampleCode.h"
      9 #include "SkCanvas.h"
     10 #include "SkPaint.h"
     11 #include "SkView.h"
     12 #include "SkLayer.h"
     13 
     14 #include "SkMatrix44.h"
     15 static void test_inv(const char label[], const SkMatrix44& mat) {
     16     SkDebugf("%s\n", label);
     17     mat.dump();
     18 
     19     SkMatrix44 inv;
     20     if (mat.invert(&inv)) {
     21         inv.dump();
     22     } else {
     23         SkDebugf("--- invert failed\n");
     24     }
     25 
     26     SkMatrix44 a, b;
     27     a.setConcat(mat, inv);
     28     b.setConcat(inv, mat);
     29     SkDebugf("concat mat with inverse pre=%d post=%d\n", a.isIdentity(), b.isIdentity());
     30     if (!a.isIdentity()) {
     31         a.dump();
     32     }
     33     if (!b.isIdentity()) {
     34         b.dump();
     35     }
     36     SkDebugf("\n");
     37 }
     38 
     39 static void test_map(SkScalar x0, SkScalar y0, SkScalar z0,
     40                      const SkMatrix44& mat,
     41                      SkScalar x1, SkScalar y1, SkScalar z1) {
     42     SkVector4 src, dst;
     43     src.set(x0, y0, z0);
     44     dst = mat * src;
     45     SkDebugf("map: src: %g %g %g dst: %g %g %g (%g) expected: %g %g %g match: %d\n",
     46              x0, y0, z0,
     47              dst.fData[0], dst.fData[1], dst.fData[2], dst.fData[3],
     48              x1, y1, z1,
     49              dst.fData[0] == x1 && dst.fData[1] == y1 && dst.fData[2] == z1);
     50 }
     51 
     52 static void test_33(const SkMatrix44& mat,
     53                     SkScalar x0, SkScalar x1, SkScalar x2,
     54                     SkScalar y0, SkScalar y1, SkScalar y2) {
     55     SkMatrix dst = mat;
     56     if (dst[0] != x0 || dst[1] != x1 || dst[2] != x2 ||
     57         dst[3] != y0 || dst[4] != y1 || dst[5] != y2) {
     58         SkString str;
     59         dst.toString(&str);
     60         SkDebugf("3x3: expected 3x3 [%g %g %g] [%g %g %g] bug got %s\n",
     61                  x0, x1, x2, y0, y1, y2, str.c_str());
     62     }
     63 }
     64 
     65 static void test44() {
     66     SkMatrix44 m0, m1, m2;
     67 
     68     test_inv("identity", m0);
     69     m0.setTranslate(2,3,4);
     70     test_inv("translate", m0);
     71     m0.setScale(2,3,4);
     72     test_inv("scale", m0);
     73     m0.postTranslate(5, 6, 7);
     74     test_inv("postTranslate", m0);
     75     m0.setScale(2,3,4);
     76     m1.setTranslate(5, 6, 7);
     77     m0.setConcat(m0, m1);
     78     test_inv("postTranslate2", m0);
     79     m0.setScale(2,3,4);
     80     m0.preTranslate(5, 6, 7);
     81     test_inv("preTranslate", m0);
     82 
     83     m0.setScale(2, 4, 6);
     84     m0.postScale(SkDoubleToMScalar(0.5));
     85     test_inv("scale/postscale to 1,2,3", m0);
     86 
     87     m0.reset();
     88     test_map(1, 0, 0, m0, 1, 0, 0);
     89     test_map(0, 1, 0, m0, 0, 1, 0);
     90     test_map(0, 0, 1, m0, 0, 0, 1);
     91     m0.setScale(2, 3, 4);
     92     test_map(1, 0, 0, m0, 2, 0, 0);
     93     test_map(0, 1, 0, m0, 0, 3, 0);
     94     test_map(0, 0, 1, m0, 0, 0, 4);
     95     m0.setTranslate(2, 3, 4);
     96     test_map(0, 0, 0, m0, 2, 3, 4);
     97     m0.preScale(5, 6, 7);
     98     test_map(1, 0, 0, m0, 7, 3, 4);
     99     test_map(0, 1, 0, m0, 2, 9, 4);
    100     test_map(0, 0, 1, m0, 2, 3, 11);
    101 
    102     SkMScalar deg = 45;
    103     m0.setRotateDegreesAbout(0, 0, 1, deg);
    104     test_map(1, 0, 0, m0, 0.707106769, -0.707106769, 0);
    105 
    106     m0.reset();
    107     test_33(m0, 1, 0, 0, 0, 1, 0);
    108     m0.setTranslate(3, 4, 5);
    109     test_33(m0, 1, 0, 3, 0, 1, 4);
    110 }
    111 
    112 ///////////////////////////////////////////////////////////////////////////////
    113 
    114 static void dump_layers(const SkLayer* layer, int tab = 0) {
    115     SkMatrix matrix;
    116     SkString matrixStr;
    117 
    118     layer->getLocalTransform(&matrix);
    119     matrix.toString(&matrixStr);
    120 
    121     for (int j = 0; j < tab; j++) {
    122         SkDebugf(" ");
    123     }
    124     SkDebugf("layer=%p parent=%p size=[%g %g] transform=%s\n",
    125              layer, layer->getParent(), layer->getWidth(), layer->getHeight(),
    126              matrixStr.c_str());
    127     for (int i = 0; i < layer->countChildren(); i++) {
    128         dump_layers(layer->getChild(i), tab + 4);
    129     }
    130 }
    131 
    132 class TestLayer : public SkLayer {
    133 public:
    134     TestLayer(SkColor c) : fColor(c) {}
    135 
    136 protected:
    137     virtual void onDraw(SkCanvas* canvas, SkScalar opacity) {
    138         SkRect r;
    139         r.set(0, 0, this->getWidth(), this->getHeight());
    140 
    141         SkPaint paint;
    142         paint.setColor(fColor);
    143         paint.setAlpha(SkScalarRoundToInt(opacity * 255));
    144 
    145         canvas->drawRect(r, paint);
    146     }
    147 
    148 private:
    149     SkColor fColor;
    150 };
    151 
    152 class SkLayerView : public SkView {
    153 private:
    154     SkLayer* fRootLayer;
    155     SkLayer* fLastChild;
    156 public:
    157     SkLayerView() {
    158         test44();
    159         static const int W = 600;
    160         static const int H = 440;
    161         static const struct {
    162             int fWidth;
    163             int fHeight;
    164             SkColor fColor;
    165             int fPosX;
    166             int fPosY;
    167         } gData[] = {
    168             { 120, 80, SK_ColorRED, 0, 0 },
    169             { 120, 80, SK_ColorGREEN, W - 120, 0 },
    170             { 120, 80, SK_ColorBLUE, 0, H - 80 },
    171             { 120, 80, SK_ColorMAGENTA, W - 120, H - 80 },
    172         };
    173 
    174         fRootLayer = new TestLayer(0xFFDDDDDD);
    175         fRootLayer->setSize(W, H);
    176         for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
    177             SkLayer* child = new TestLayer(gData[i].fColor);
    178             child->setSize(gData[i].fWidth, gData[i].fHeight);
    179             child->setPosition(gData[i].fPosX, gData[i].fPosY);
    180             fRootLayer->addChild(child)->unref();
    181         }
    182 
    183         SkLayer* child = new TestLayer(0xFFDD8844);
    184         child->setSize(120, 80);
    185         child->setPosition(fRootLayer->getWidth()/2 - child->getWidth()/2,
    186                            fRootLayer->getHeight()/2 - child->getHeight()/2);
    187         child->setAnchorPoint(SK_ScalarHalf, SK_ScalarHalf);
    188         {
    189             SkMatrix m;
    190             m.setRotate(SkIntToScalar(30));
    191             child->setMatrix(m);
    192         }
    193         fLastChild = child;
    194         fRootLayer->addChild(child)->unref();
    195 
    196         if (false) {
    197             SkMatrix matrix;
    198             matrix.setScale(0.5, 0.5);
    199             fRootLayer->setMatrix(matrix);
    200         }
    201 
    202 //        dump_layers(fRootLayer);
    203     }
    204 
    205     virtual ~SkLayerView() {
    206         SkSafeUnref(fRootLayer);
    207     }
    208 
    209 protected:
    210     // overrides from SkEventSink
    211     virtual bool onQuery(SkEvent* evt) {
    212         if (SampleCode::TitleQ(*evt)) {
    213             SampleCode::TitleR(evt, "SkLayer");
    214             return true;
    215         }
    216         return this->INHERITED::onQuery(evt);
    217     }
    218 
    219     virtual void onDraw(SkCanvas* canvas) {
    220         canvas->drawColor(SK_ColorWHITE);
    221 
    222         canvas->translate(20, 20);
    223         fRootLayer->draw(canvas);
    224 
    225         // visual test of getLocalTransform
    226         if (true) {
    227             SkMatrix matrix;
    228             fLastChild->localToGlobal(&matrix);
    229             SkPaint paint;
    230             paint.setStyle(SkPaint::kStroke_Style);
    231             paint.setStrokeWidth(5);
    232             paint.setColor(0x88FF0000);
    233             canvas->concat(matrix);
    234             canvas->drawRect(SkRect::MakeSize(fLastChild->getSize()), paint);
    235         }
    236     }
    237 
    238 private:
    239     typedef SkView INHERITED;
    240 };
    241 
    242 ///////////////////////////////////////////////////////////////////////////////
    243 
    244 static SkView* MyFactory() { return new SkLayerView; }
    245 static SkViewRegister reg(MyFactory);
    246