-
Notifications
You must be signed in to change notification settings - Fork 8
/
10354.diff
161 lines (144 loc) · 5.87 KB
/
10354.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
commit f026d896dce856dd3c757c4c341b2df6876e1d28
Author: Robert Phillips <[email protected]>
Date: Fri Sep 14 11:07:00 2018 -0400
Preserve fLastMoveToIndex in SkPath::transform
This should remedy some of the SkPath::reverseAddPath fuzzer failures
Change-Id: Ic9fe6106b4a0693084b75f0544b672cea78be3cc
Reviewed-on: https://skia-review.googlesource.com/154625
Reviewed-by: Cary Clark <[email protected]>
Commit-Queue: Robert Phillips <[email protected]>
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 2808c12ed4..bfe9cc23c9 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1711,60 +1711,60 @@ SkPath& SkPath::reversePathTo(const SkPath& path) {
SkPath& SkPath::reverseAddPath(const SkPath& srcPath) {
// Detect if we're trying to add ourself
const SkPath* src = &srcPath;
SkTLazy<SkPath> tmp;
if (this == src) {
src = tmp.set(srcPath);
}
- SkPathRef::Editor ed(&fPathRef, src->fPathRef->countPoints(), src->fPathRef->countVerbs());
+ SkPathRef::Editor ed(&fPathRef, src->countVerbs(), src->countPoints());
const SkPoint* pts = src->fPathRef->pointsEnd();
- // we will iterator through src's verbs backwards
+ // we will iterate through src's verbs backwards
const uint8_t* verbs = src->fPathRef->verbsMemBegin(); // points at the last verb
const uint8_t* verbsEnd = src->fPathRef->verbs(); // points just past the first verb
const SkScalar* conicWeights = src->fPathRef->conicWeightsEnd();
bool needMove = true;
bool needClose = false;
while (verbs < verbsEnd) {
uint8_t v = *(verbs++);
int n = pts_in_verb(v);
if (needMove) {
--pts;
this->moveTo(pts->fX, pts->fY);
needMove = false;
}
pts -= n;
switch (v) {
case kMove_Verb:
if (needClose) {
this->close();
needClose = false;
}
needMove = true;
pts += 1; // so we see the point in "if (needMove)" above
break;
case kLine_Verb:
this->lineTo(pts[0]);
break;
case kQuad_Verb:
this->quadTo(pts[1], pts[0]);
break;
case kConic_Verb:
this->conicTo(pts[1], pts[0], *--conicWeights);
break;
case kCubic_Verb:
this->cubicTo(pts[2], pts[1], pts[0]);
break;
case kClose_Verb:
needClose = true;
break;
default:
SkDEBUGFAIL("unexpected verb");
}
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1792,79 +1792,80 @@ static void subdivide_cubic_to(SkPath* path, const SkPoint pts[4],
void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const {
SkDEBUGCODE(this->validate();)
if (dst == nullptr) {
dst = (SkPath*)this;
}
if (matrix.hasPerspective()) {
SkPath tmp;
tmp.fFillType = fFillType;
SkPath::Iter iter(*this, false);
SkPoint pts[4];
SkPath::Verb verb;
while ((verb = iter.next(pts, false)) != kDone_Verb) {
switch (verb) {
case kMove_Verb:
tmp.moveTo(pts[0]);
break;
case kLine_Verb:
tmp.lineTo(pts[1]);
break;
case kQuad_Verb:
// promote the quad to a conic
tmp.conicTo(pts[1], pts[2],
SkConic::TransformW(pts, SK_Scalar1, matrix));
break;
case kConic_Verb:
tmp.conicTo(pts[1], pts[2],
SkConic::TransformW(pts, iter.conicWeight(), matrix));
break;
case kCubic_Verb:
subdivide_cubic_to(&tmp, pts);
break;
case kClose_Verb:
tmp.close();
break;
default:
SkDEBUGFAIL("unknown verb");
break;
}
}
dst->swap(tmp);
SkPathRef::Editor ed(&dst->fPathRef);
matrix.mapPoints(ed.points(), ed.pathRef()->countPoints());
dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
} else {
SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix);
if (this != dst) {
+ dst->fLastMoveToIndex = fLastMoveToIndex;
dst->fFillType = fFillType;
dst->fConvexity.store(fConvexity);
dst->fIsVolatile = fIsVolatile;
}
if (SkPathPriv::kUnknown_FirstDirection == fFirstDirection) {
dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
} else {
SkScalar det2x2 =
matrix.get(SkMatrix::kMScaleX) * matrix.get(SkMatrix::kMScaleY) -
matrix.get(SkMatrix::kMSkewX) * matrix.get(SkMatrix::kMSkewY);
if (det2x2 < 0) {
dst->fFirstDirection = SkPathPriv::OppositeFirstDirection(
(SkPathPriv::FirstDirection)fFirstDirection.load());
} else if (det2x2 > 0) {
dst->fFirstDirection = fFirstDirection.load();
} else {
dst->fConvexity = kUnknown_Convexity;
dst->fFirstDirection = SkPathPriv::kUnknown_FirstDirection;
}
}
SkDEBUGCODE(dst->validate();)
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////