• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
test_inv(const char label[],const SkMatrix44 & mat)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 
test_map(SkScalar x0,SkScalar y0,SkScalar z0,const SkMatrix44 & mat,SkScalar x1,SkScalar y1,SkScalar z1)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 
test_33(const SkMatrix44 & mat,SkScalar x0,SkScalar x1,SkScalar x2,SkScalar y0,SkScalar y1,SkScalar y2)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 
test44()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 
dump_layers(const SkLayer * layer,int tab=0)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:
TestLayer(SkColor c)134     TestLayer(SkColor c) : fColor(c) {}
135 
136 protected:
onDraw(SkCanvas * canvas,SkScalar opacity)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:
SkLayerView()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 
~SkLayerView()205     virtual ~SkLayerView() {
206         SkSafeUnref(fRootLayer);
207     }
208 
209 protected:
210     // overrides from SkEventSink
onQuery(SkEvent * evt)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 
onDraw(SkCanvas * canvas)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 
MyFactory()244 static SkView* MyFactory() { return new SkLayerView; }
245 static SkViewRegister reg(MyFactory);
246