1
2/*
3 * Copyright 2006 The Android Open Source Project
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
9
10#include "SkMatrixParts.h"
11#include "SkAnimateMaker.h"
12#include "SkDrawMatrix.h"
13#include "SkDrawRectangle.h"
14#include "SkDrawPath.h"
15
16SkMatrixPart::SkMatrixPart() : fMatrix(NULL) {
17}
18
19void SkMatrixPart::dirty() {
20    fMatrix->dirty();
21}
22
23SkDisplayable* SkMatrixPart::getParent() const {
24    return fMatrix;
25}
26
27bool SkMatrixPart::setParent(SkDisplayable* parent) {
28    SkASSERT(parent != NULL);
29    if (parent->isMatrix() == false)
30        return true;
31    fMatrix = (SkDrawMatrix*) parent;
32    return false;
33}
34
35
36#if SK_USE_CONDENSED_INFO == 0
37
38const SkMemberInfo SkRotate::fInfo[] = {
39    SK_MEMBER(center, Point),
40    SK_MEMBER(degrees, Float)
41};
42
43#endif
44
45DEFINE_GET_MEMBER(SkRotate);
46
47SkRotate::SkRotate() : degrees(0) {
48    center.fX = center.fY = 0;
49}
50
51bool SkRotate::add() {
52    fMatrix->rotate(degrees, center);
53    return false;
54}
55
56
57#if SK_USE_CONDENSED_INFO == 0
58
59const SkMemberInfo SkScale::fInfo[] = {
60    SK_MEMBER(center, Point),
61    SK_MEMBER(x, Float),
62    SK_MEMBER(y, Float)
63};
64
65#endif
66
67DEFINE_GET_MEMBER(SkScale);
68
69SkScale::SkScale() : x(SK_Scalar1), y(SK_Scalar1) {
70    center.fX = center.fY = 0;
71}
72
73bool SkScale::add() {
74    fMatrix->scale(x, y, center);
75    return false;
76}
77
78
79#if SK_USE_CONDENSED_INFO == 0
80
81const SkMemberInfo SkSkew::fInfo[] = {
82    SK_MEMBER(center, Point),
83    SK_MEMBER(x, Float),
84    SK_MEMBER(y, Float)
85};
86
87#endif
88
89DEFINE_GET_MEMBER(SkSkew);
90
91SkSkew::SkSkew() : x(0), y(0) {
92    center.fX = center.fY = 0;
93}
94
95bool SkSkew::add() {
96    fMatrix->skew(x, y, center);
97    return false;
98}
99
100
101#if SK_USE_CONDENSED_INFO == 0
102
103const SkMemberInfo SkTranslate::fInfo[] = {
104    SK_MEMBER(x, Float),
105    SK_MEMBER(y, Float)
106};
107
108#endif
109
110DEFINE_GET_MEMBER(SkTranslate);
111
112SkTranslate::SkTranslate() : x(0), y(0) {
113}
114
115bool SkTranslate::add() {
116    fMatrix->translate(x, y);
117    return false;
118}
119
120
121#if SK_USE_CONDENSED_INFO == 0
122
123const SkMemberInfo SkFromPath::fInfo[] = {
124    SK_MEMBER(mode, FromPathMode),
125    SK_MEMBER(offset, Float),
126    SK_MEMBER(path, Path)
127};
128
129#endif
130
131DEFINE_GET_MEMBER(SkFromPath);
132
133SkFromPath::SkFromPath() :
134    mode(0), offset(0), path(NULL) {
135}
136
137SkFromPath::~SkFromPath() {
138}
139
140bool SkFromPath::add() {
141    if (path == NULL)
142        return true;
143    static const uint8_t gFlags[] = {
144        SkPathMeasure::kGetPosAndTan_MatrixFlag,    // normal
145        SkPathMeasure::kGetTangent_MatrixFlag,      // angle
146        SkPathMeasure::kGetPosition_MatrixFlag      // position
147    };
148    if ((unsigned)mode >= SK_ARRAY_COUNT(gFlags))
149        return true;
150    SkMatrix result;
151    fPathMeasure.setPath(&path->getPath(), false);
152    if (fPathMeasure.getMatrix(offset, &result, (SkPathMeasure::MatrixFlags)gFlags[mode]))
153        fMatrix->set(result);
154    return false;
155}
156
157
158#if SK_USE_CONDENSED_INFO == 0
159
160const SkMemberInfo SkRectToRect::fInfo[] = {
161    SK_MEMBER(destination, Rect),
162    SK_MEMBER(source, Rect)
163};
164
165#endif
166
167DEFINE_GET_MEMBER(SkRectToRect);
168
169SkRectToRect::SkRectToRect() :
170    source(NULL), destination(NULL) {
171}
172
173SkRectToRect::~SkRectToRect() {
174}
175
176bool SkRectToRect::add() {
177    if (source == NULL || destination == NULL)
178        return true;
179    SkMatrix temp;
180    temp.setRectToRect(source->fRect, destination->fRect,
181                       SkMatrix::kFill_ScaleToFit);
182    fMatrix->set(temp);
183    return false;
184}
185
186#ifdef SK_DUMP_ENABLED
187void SkRectToRect::dump(SkAnimateMaker* maker) {
188    dumpBase(maker);
189    SkDebugf("/>\n");
190    SkDisplayList::fIndent += 4;
191    if (source) {
192        SkDebugf("%*s<source>\n", SkDisplayList::fIndent, "");
193        SkDisplayList::fIndent += 4;
194        source->dump(maker);
195        SkDisplayList::fIndent -= 4;
196        SkDebugf("%*s</source>\n", SkDisplayList::fIndent, "");
197    }
198    if (destination) {
199        SkDebugf("%*s<destination>\n", SkDisplayList::fIndent, "");
200        SkDisplayList::fIndent += 4;
201        destination->dump(maker);
202        SkDisplayList::fIndent -= 4;
203        SkDebugf("%*s</destination>\n", SkDisplayList::fIndent, "");
204    }
205    SkDisplayList::fIndent -= 4;
206    dumpEnd(maker);
207}
208#endif
209
210const SkMemberInfo* SkRectToRect::preferredChild(SkDisplayTypes ) {
211    if (source == NULL)
212        return getMember("source"); // !!! cwap! need to refer to member through enum like kScope instead
213    else {
214        SkASSERT(destination == NULL);
215        return getMember("destination");
216    }
217}
218
219
220#if SK_USE_CONDENSED_INFO == 0
221
222const SkMemberInfo SkPolyToPoly::fInfo[] = {
223    SK_MEMBER(destination, Polygon),
224    SK_MEMBER(source, Polygon)
225};
226
227#endif
228
229DEFINE_GET_MEMBER(SkPolyToPoly);
230
231SkPolyToPoly::SkPolyToPoly() : source(NULL), destination(NULL) {
232}
233
234SkPolyToPoly::~SkPolyToPoly() {
235}
236
237bool SkPolyToPoly::add() {
238    SkASSERT(source);
239    SkASSERT(destination);
240    SkPoint src[4];
241    SkPoint dst[4];
242    SkPath& sourcePath = source->getPath();
243    int srcPts = sourcePath.getPoints(src, 4);
244    SkPath& destPath = destination->getPath();
245    int dstPts = destPath.getPoints(dst, 4);
246    if (srcPts != dstPts)
247        return true;
248    SkMatrix temp;
249    temp.setPolyToPoly(src, dst, srcPts);
250    fMatrix->set(temp);
251    return false;
252}
253
254#ifdef SK_DUMP_ENABLED
255void SkPolyToPoly::dump(SkAnimateMaker* maker) {
256    dumpBase(maker);
257    SkDebugf("/>\n");
258    SkDisplayList::fIndent += 4;
259    if (source) {
260        SkDebugf("%*s<source>\n", SkDisplayList::fIndent, "");
261        SkDisplayList::fIndent += 4;
262        source->dump(maker);
263        SkDisplayList::fIndent -= 4;
264        SkDebugf("%*s</source>\n", SkDisplayList::fIndent, "");
265    }
266    if (destination) {
267        SkDebugf("%*s<destination>\n", SkDisplayList::fIndent, "");
268        SkDisplayList::fIndent += 4;
269        destination->dump(maker);
270        SkDisplayList::fIndent -= 4;
271        SkDebugf("%*s</destination>\n", SkDisplayList::fIndent, "");
272    }
273    SkDisplayList::fIndent -= 4;
274    dumpEnd(maker);
275}
276#endif
277
278void SkPolyToPoly::onEndElement(SkAnimateMaker& ) {
279    SkASSERT(source);
280    SkASSERT(destination);
281    if (source->childHasID() || destination->childHasID())
282        fMatrix->setChildHasID();
283}
284
285const SkMemberInfo* SkPolyToPoly::preferredChild(SkDisplayTypes ) {
286    if (source == NULL)
287        return getMember("source"); // !!! cwap! need to refer to member through enum like kScope instead
288    else {
289        SkASSERT(destination == NULL);
290        return getMember("destination");
291    }
292}
293