blob: 11976e9da6cf84172fc30a38699da520882c84dd [file] [log] [blame]
reed@android.comda6fb322010-02-19 21:41:30 +00001#include "SampleCode.h"
2#include "SkCanvas.h"
3#include "SkPaint.h"
4#include "SkView.h"
5#include "SkLayer.h"
6
reed@android.comc8c49c52010-02-24 15:36:57 +00007#include "SkMatrix44.h"
8static void test_inv(const char label[], const SkMatrix44& mat) {
9 SkDebugf("%s\n", label);
10 mat.dump();
11
12 SkMatrix44 inv;
13 if (mat.invert(&inv)) {
14 inv.dump();
15 } else {
16 SkDebugf("--- invert failed\n");
17 }
18
19 SkMatrix44 a, b;
20 a.setConcat(mat, inv);
21 b.setConcat(inv, mat);
22 SkDebugf("concat mat with inverse pre=%d post=%d\n", a.isIdentity(), b.isIdentity());
23 if (!a.isIdentity()) {
24 a.dump();
25 }
26 if (!b.isIdentity()) {
27 b.dump();
28 }
29 SkDebugf("\n");
30}
31
reed@android.comb5d0f7b2010-02-24 22:08:58 +000032static void test_map(SkScalar x0, SkScalar y0, SkScalar z0,
33 const SkMatrix44& mat,
34 SkScalar x1, SkScalar y1, SkScalar z1) {
35 SkVector4 src, dst;
36 src.set(x0, y0, z0);
37 dst = mat * src;
38 SkDebugf("map: src: %g %g %g dst: %g %g %g (%g) expected: %g %g %g match: %d\n",
39 x0, y0, z0,
40 dst.fData[0], dst.fData[1], dst.fData[2], dst.fData[3],
41 x1, y1, z1,
42 dst.fData[0] == x1 && dst.fData[1] == y1 && dst.fData[2] == z1);
43}
reed@android.com7d970c72010-04-22 16:07:49 +000044
45static void test_33(const SkMatrix44& mat,
46 SkScalar x0, SkScalar x1, SkScalar x2,
47 SkScalar y0, SkScalar y1, SkScalar y2) {
48 SkMatrix dst = mat;
49 if (dst[0] != x0 || dst[1] != x1 || dst[2] != x2 ||
50 dst[3] != y0 || dst[4] != y1 || dst[5] != y2) {
51 SkString str;
52 dst.toDumpString(&str);
53 SkDebugf("3x3: expected 3x3 [%g %g %g] [%g %g %g] bug got %s\n",
54 x0, x1, x2, y0, y1, y2, str.c_str());
55 }
56}
57
reed@android.comc8c49c52010-02-24 15:36:57 +000058static void test44() {
59 SkMatrix44 m0, m1, m2;
60
61 test_inv("identity", m0);
62 m0.setTranslate(2,3,4);
63 test_inv("translate", m0);
64 m0.setScale(2,3,4);
65 test_inv("scale", m0);
66 m0.postTranslate(5, 6, 7);
67 test_inv("postTranslate", m0);
68 m0.setScale(2,3,4);
69 m1.setTranslate(5, 6, 7);
70 m0.setConcat(m0, m1);
71 test_inv("postTranslate2", m0);
72 m0.setScale(2,3,4);
73 m0.preTranslate(5, 6, 7);
74 test_inv("preTranslate", m0);
75
76 m0.setScale(2, 4, 6);
77 m0.postScale(SkDoubleToMScalar(0.5));
78 test_inv("scale/postscale to 1,2,3", m0);
reed@android.comb5d0f7b2010-02-24 22:08:58 +000079
80 m0.reset();
81 test_map(1, 0, 0, m0, 1, 0, 0);
82 test_map(0, 1, 0, m0, 0, 1, 0);
83 test_map(0, 0, 1, m0, 0, 0, 1);
84 m0.setScale(2, 3, 4);
85 test_map(1, 0, 0, m0, 2, 0, 0);
86 test_map(0, 1, 0, m0, 0, 3, 0);
87 test_map(0, 0, 1, m0, 0, 0, 4);
88 m0.setTranslate(2, 3, 4);
89 test_map(0, 0, 0, m0, 2, 3, 4);
90 m0.preScale(5, 6, 7);
91 test_map(1, 0, 0, m0, 7, 3, 4);
92 test_map(0, 1, 0, m0, 2, 9, 4);
93 test_map(0, 0, 1, m0, 2, 3, 11);
reed@android.com7d970c72010-04-22 16:07:49 +000094
95 SkMScalar deg = 45;
96 m0.setRotateDegreesAbout(0, 0, 1, deg);
97 test_map(1, 0, 0, m0, 0.707106769, -0.707106769, 0);
98
99 m0.reset();
100 test_33(m0, 1, 0, 0, 0, 1, 0);
101 m0.setTranslate(3, 4, 5);
102 test_33(m0, 1, 0, 3, 0, 1, 4);
reed@android.comc8c49c52010-02-24 15:36:57 +0000103}
104
reed@android.comda6fb322010-02-19 21:41:30 +0000105///////////////////////////////////////////////////////////////////////////////
106
reed@android.com745bfbd2010-02-24 17:16:35 +0000107static void dump_layers(const SkLayer* layer, int tab = 0) {
108 SkMatrix matrix;
109 SkString matrixStr;
110
111 layer->getLocalTransform(&matrix);
112 matrix.toDumpString(&matrixStr);
113
114 for (int j = 0; j < tab; j++) {
115 SkDebugf(" ");
116 }
117 SkDebugf("layer=%p parent=%p size=[%g %g] transform=%s\n",
118 layer, layer->getParent(), layer->getWidth(), layer->getHeight(),
119 matrixStr.c_str());
120 for (int i = 0; i < layer->countChildren(); i++) {
121 dump_layers(layer->getChild(i), tab + 4);
122 }
123}
124
reed@android.comda6fb322010-02-19 21:41:30 +0000125class TestLayer : public SkLayer {
126public:
127 TestLayer(SkColor c) : fColor(c) {}
128
129protected:
130 virtual void onDraw(SkCanvas* canvas, SkScalar opacity) {
131 SkRect r;
132 r.set(0, 0, this->getWidth(), this->getHeight());
133
134 SkPaint paint;
135 paint.setColor(fColor);
136 paint.setAlpha(SkScalarRound(opacity * 255));
137
138 canvas->drawRect(r, paint);
139 }
140
141private:
142 SkColor fColor;
143};
144
145class SkLayerView : public SkView {
146private:
147 SkLayer* fRootLayer;
reed@android.com745bfbd2010-02-24 17:16:35 +0000148 SkLayer* fLastChild;
reed@android.comda6fb322010-02-19 21:41:30 +0000149public:
150 SkLayerView() {
reed@android.comc8c49c52010-02-24 15:36:57 +0000151 test44();
reed@android.com2bd703b2010-02-24 02:01:23 +0000152 static const int W = 600;
153 static const int H = 440;
reed@android.comda6fb322010-02-19 21:41:30 +0000154 static const struct {
155 int fWidth;
156 int fHeight;
157 SkColor fColor;
158 int fPosX;
159 int fPosY;
160 } gData[] = {
161 { 120, 80, SK_ColorRED, 0, 0 },
162 { 120, 80, SK_ColorGREEN, W - 120, 0 },
163 { 120, 80, SK_ColorBLUE, 0, H - 80 },
164 { 120, 80, SK_ColorMAGENTA, W - 120, H - 80 },
165 };
166
reed@android.com2bd703b2010-02-24 02:01:23 +0000167 fRootLayer = new TestLayer(0xFFDDDDDD);
reed@android.comda6fb322010-02-19 21:41:30 +0000168 fRootLayer->setSize(W, H);
169 for (size_t i = 0; i < SK_ARRAY_COUNT(gData); i++) {
170 SkLayer* child = new TestLayer(gData[i].fColor);
171 child->setSize(gData[i].fWidth, gData[i].fHeight);
172 child->setPosition(gData[i].fPosX, gData[i].fPosY);
173 fRootLayer->addChild(child)->unref();
174 }
reed@android.com2bd703b2010-02-24 02:01:23 +0000175
176 SkLayer* child = new TestLayer(0xFFDD8844);
177 child->setSize(120, 80);
178 child->setPosition(fRootLayer->getWidth()/2 - child->getWidth()/2,
179 fRootLayer->getHeight()/2 - child->getHeight()/2);
180 child->setAnchorPoint(SK_ScalarHalf, SK_ScalarHalf);
181 {
182 SkMatrix m;
183 m.setRotate(SkIntToScalar(30));
184 child->setMatrix(m);
185 }
reed@android.com745bfbd2010-02-24 17:16:35 +0000186 fLastChild = child;
reed@android.com2bd703b2010-02-24 02:01:23 +0000187 fRootLayer->addChild(child)->unref();
reed@android.com745bfbd2010-02-24 17:16:35 +0000188
189 if (false) {
190 SkMatrix matrix;
191 matrix.setScale(0.5, 0.5);
192 fRootLayer->setMatrix(matrix);
193 }
194
reed@android.comb5d0f7b2010-02-24 22:08:58 +0000195// dump_layers(fRootLayer);
reed@android.comda6fb322010-02-19 21:41:30 +0000196 }
197
198 virtual ~SkLayerView() {
199 SkSafeUnref(fRootLayer);
200 }
201
202protected:
203 // overrides from SkEventSink
204 virtual bool onQuery(SkEvent* evt) {
205 if (SampleCode::TitleQ(*evt)) {
206 SampleCode::TitleR(evt, "SkLayer");
207 return true;
208 }
209 return this->INHERITED::onQuery(evt);
210 }
211
reed@android.com745bfbd2010-02-24 17:16:35 +0000212 virtual void onDraw(SkCanvas* canvas) {
reed@android.com2bd703b2010-02-24 02:01:23 +0000213 canvas->drawColor(SK_ColorWHITE);
reed@android.com745bfbd2010-02-24 17:16:35 +0000214
reed@android.com2bd703b2010-02-24 02:01:23 +0000215 canvas->translate(20, 20);
reed@android.comda6fb322010-02-19 21:41:30 +0000216 fRootLayer->draw(canvas);
reed@android.com745bfbd2010-02-24 17:16:35 +0000217
218 // visual test of getLocalTransform
219 if (true) {
220 SkMatrix matrix;
221 fLastChild->localToGlobal(&matrix);
222 SkPaint paint;
223 paint.setStyle(SkPaint::kStroke_Style);
224 paint.setStrokeWidth(5);
225 paint.setColor(0x88FF0000);
226 canvas->concat(matrix);
227 canvas->drawRect(SkRect::MakeSize(fLastChild->getSize()), paint);
228 }
reed@android.comda6fb322010-02-19 21:41:30 +0000229 }
230
reed@android.comda6fb322010-02-19 21:41:30 +0000231private:
232 typedef SkView INHERITED;
233};
234
235///////////////////////////////////////////////////////////////////////////////
236
237static SkView* MyFactory() { return new SkLayerView; }
238static SkViewRegister reg(MyFactory);
239