Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / tests / PathOpsTestCommon.cpp
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "PathOpsTestCommon.h"
8 #include "SkPathOpsBounds.h"
9 #include "SkPathOpsCubic.h"
10 #include "SkPathOpsLine.h"
11 #include "SkPathOpsQuad.h"
12 #include "SkPathOpsTriangle.h"
13
14 void CubicToQuads(const SkDCubic& cubic, double precision, SkTArray<SkDQuad, true>& quads) {
15     SkTArray<double, true> ts;
16     cubic.toQuadraticTs(precision, &ts);
17     if (ts.count() <= 0) {
18         SkDQuad quad = cubic.toQuad();
19         quads.push_back(quad);
20         return;
21     }
22     double tStart = 0;
23     for (int i1 = 0; i1 <= ts.count(); ++i1) {
24         const double tEnd = i1 < ts.count() ? ts[i1] : 1;
25         SkDCubic part = cubic.subDivide(tStart, tEnd);
26         SkDQuad quad = part.toQuad();
27         quads.push_back(quad);
28         tStart = tEnd;
29     }
30 }
31
32 void CubicPathToQuads(const SkPath& cubicPath, SkPath* quadPath) {
33     quadPath->reset();
34     SkDCubic cubic;
35     SkTArray<SkDQuad, true> quads;
36     SkPath::RawIter iter(cubicPath);
37     uint8_t verb;
38     SkPoint pts[4];
39     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
40         switch (verb) {
41             case SkPath::kMove_Verb:
42                 quadPath->moveTo(pts[0].fX, pts[0].fY);
43                 continue;
44             case SkPath::kLine_Verb:
45                 quadPath->lineTo(pts[1].fX, pts[1].fY);
46                 break;
47             case SkPath::kQuad_Verb:
48                 quadPath->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
49                 break;
50             case SkPath::kCubic_Verb:
51                 quads.reset();
52                 cubic.set(pts);
53                 CubicToQuads(cubic, cubic.calcPrecision(), quads);
54                 for (int index = 0; index < quads.count(); ++index) {
55                     SkPoint qPts[2] = {
56                         quads[index][1].asSkPoint(),
57                         quads[index][2].asSkPoint()
58                     };
59                     quadPath->quadTo(qPts[0].fX, qPts[0].fY, qPts[1].fX, qPts[1].fY);
60                 }
61                 break;
62             case SkPath::kClose_Verb:
63                  quadPath->close();
64                 break;
65             default:
66                 SkDEBUGFAIL("bad verb");
67                 return;
68         }
69     }
70 }
71
72 void CubicPathToSimple(const SkPath& cubicPath, SkPath* simplePath) {
73     simplePath->reset();
74     SkDCubic cubic;
75     SkPath::RawIter iter(cubicPath);
76     uint8_t verb;
77     SkPoint pts[4];
78     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
79         switch (verb) {
80             case SkPath::kMove_Verb:
81                 simplePath->moveTo(pts[0].fX, pts[0].fY);
82                 continue;
83             case SkPath::kLine_Verb:
84                 simplePath->lineTo(pts[1].fX, pts[1].fY);
85                 break;
86             case SkPath::kQuad_Verb:
87                 simplePath->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
88                 break;
89             case SkPath::kCubic_Verb: {
90                 cubic.set(pts);
91                 double tInflects[2];
92                 int inflections = cubic.findInflections(tInflects);
93                 if (inflections > 1 && tInflects[0] > tInflects[1]) {
94                     SkTSwap(tInflects[0], tInflects[1]);
95                 }
96                 double lo = 0;
97                 for (int index = 0; index <= inflections; ++index) {
98                     double hi = index < inflections ? tInflects[index] : 1;
99                     SkDCubic part = cubic.subDivide(lo, hi);
100                     SkPoint cPts[3];
101                     cPts[0] = part[1].asSkPoint();
102                     cPts[1] = part[2].asSkPoint();
103                     cPts[2] = part[3].asSkPoint();
104                     simplePath->cubicTo(cPts[0].fX, cPts[0].fY, cPts[1].fX, cPts[1].fY,
105                             cPts[2].fX, cPts[2].fY);
106                     lo = hi;
107                 }
108                 break;
109             } 
110             case SkPath::kClose_Verb:
111                  simplePath->close();
112                 break;
113             default:
114                 SkDEBUGFAIL("bad verb");
115                 return;
116         }
117     }
118 }
119
120 static bool SkDoubleIsNaN(double x) {
121     return x != x;
122 }
123
124 bool ValidBounds(const SkPathOpsBounds& bounds) {
125     if (SkScalarIsNaN(bounds.fLeft)) {
126         return false;
127     }
128     if (SkScalarIsNaN(bounds.fTop)) {
129         return false;
130     }
131     if (SkScalarIsNaN(bounds.fRight)) {
132         return false;
133     }
134     return !SkScalarIsNaN(bounds.fBottom);
135 }
136
137 bool ValidCubic(const SkDCubic& cubic) {
138     for (int index = 0; index < 4; ++index) {
139         if (!ValidPoint(cubic[index])) {
140             return false;
141         }
142     }
143     return true;
144 }
145
146 bool ValidLine(const SkDLine& line) {
147     for (int index = 0; index < 2; ++index) {
148         if (!ValidPoint(line[index])) {
149             return false;
150         }
151     }
152     return true;
153 }
154
155 bool ValidPoint(const SkDPoint& pt) {
156     if (SkDoubleIsNaN(pt.fX)) {
157         return false;
158     }
159     return !SkDoubleIsNaN(pt.fY);
160 }
161
162 bool ValidPoints(const SkPoint* pts, int count) {
163     for (int index = 0; index < count; ++index) {
164         if (SkScalarIsNaN(pts[index].fX)) {
165             return false;
166         }
167         if (SkScalarIsNaN(pts[index].fY)) {
168             return false;
169         }
170     }
171     return true;
172 }
173
174 bool ValidQuad(const SkDQuad& quad) {
175     for (int index = 0; index < 3; ++index) {
176         if (!ValidPoint(quad[index])) {
177             return false;
178         }
179     }
180     return true;
181 }
182
183 bool ValidTriangle(const SkDTriangle& triangle) {
184     for (int index = 0; index < 3; ++index) {
185         if (!ValidPoint(triangle.fPts[index])) {
186             return false;
187         }
188     }
189     return true;
190 }
191
192 bool ValidVector(const SkDVector& v) {
193     if (SkDoubleIsNaN(v.fX)) {
194         return false;
195     }
196     return !SkDoubleIsNaN(v.fY);
197 }