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