OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrShape_DEFINED | 8 #ifndef GrShape_DEFINED |
9 #define GrShape_DEFINED | 9 #define GrShape_DEFINED |
10 | 10 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 if (inverted) { | 145 if (inverted) { |
146 *inverted = fRRectData.fInverted; | 146 *inverted = fRRectData.fInverted; |
147 } | 147 } |
148 return true; | 148 return true; |
149 } | 149 } |
150 | 150 |
151 /** | 151 /** |
152 * If the unstyled shape is a straight line segment, returns true and sets p
ts to the endpoints. | 152 * If the unstyled shape is a straight line segment, returns true and sets p
ts to the endpoints. |
153 * An inverse filled line path is still considered a line. | 153 * An inverse filled line path is still considered a line. |
154 */ | 154 */ |
155 bool asLine(SkPoint pts[2]) const { | 155 bool asLine(SkPoint pts[2], bool* inverted) const { |
156 if (fType != Type::kPath) { | 156 if (fType != Type::kLine) { |
157 return false; | 157 return false; |
158 } | 158 } |
159 return this->path().isLine(pts); | 159 if (pts) { |
160 } | 160 pts[0] = fLineData.fPts[0]; |
| 161 pts[1] = fLineData.fPts[1]; |
| 162 } |
| 163 if (inverted) { |
| 164 *inverted = fLineData.fInverted; |
| 165 } |
| 166 return true; |
| 167 } |
161 | 168 |
162 /** Returns the unstyled geometry as a path. */ | 169 /** Returns the unstyled geometry as a path. */ |
163 void asPath(SkPath* out) const { | 170 void asPath(SkPath* out) const { |
164 switch (fType) { | 171 switch (fType) { |
165 case Type::kEmpty: | 172 case Type::kEmpty: |
166 out->reset(); | 173 out->reset(); |
167 break; | 174 break; |
168 case Type::kRRect: | 175 case Type::kRRect: |
169 out->reset(); | 176 out->reset(); |
170 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt
art); | 177 out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fSt
art); |
171 // Below matches the fill type that attemptToSimplifyPath uses. | 178 // Below matches the fill type that attemptToSimplifyPath uses. |
172 if (fRRectData.fInverted) { | 179 if (fRRectData.fInverted) { |
173 out->setFillType(kDefaultPathInverseFillType); | 180 out->setFillType(kDefaultPathInverseFillType); |
174 } else { | 181 } else { |
175 out->setFillType(kDefaultPathFillType); | 182 out->setFillType(kDefaultPathFillType); |
176 } | 183 } |
177 break; | 184 break; |
| 185 case Type::kLine: |
| 186 out->reset(); |
| 187 out->moveTo(fLineData.fPts[0]); |
| 188 out->lineTo(fLineData.fPts[1]); |
| 189 if (fLineData.fInverted) { |
| 190 out->setFillType(kDefaultPathInverseFillType); |
| 191 } else { |
| 192 out->setFillType(kDefaultPathFillType); |
| 193 } |
| 194 break; |
178 case Type::kPath: | 195 case Type::kPath: |
179 *out = this->path(); | 196 *out = this->path(); |
180 break; | 197 break; |
181 } | 198 } |
182 } | 199 } |
183 | 200 |
184 /** | 201 /** |
185 * Returns whether the geometry is empty. Note that applying the style could
produce a | 202 * Returns whether the geometry is empty. Note that applying the style could
produce a |
186 * non-empty shape. | 203 * non-empty shape. |
187 */ | 204 */ |
188 bool isEmpty() const { return Type::kEmpty == fType; } | 205 bool isEmpty() const { return Type::kEmpty == fType; } |
189 | 206 |
190 /** | 207 /** |
191 * Gets the bounds of the geometry without reflecting the shape's styling. T
his ignores | 208 * Gets the bounds of the geometry without reflecting the shape's styling. T
his ignores |
192 * the inverse fill nature of the geometry. | 209 * the inverse fill nature of the geometry. |
193 */ | 210 */ |
194 const SkRect& bounds() const; | 211 SkRect bounds() const; |
195 | 212 |
196 /** | 213 /** |
197 * Gets the bounds of the geometry reflecting the shape's styling (ignoring
inverse fill | 214 * Gets the bounds of the geometry reflecting the shape's styling (ignoring
inverse fill |
198 * status). | 215 * status). |
199 */ | 216 */ |
200 void styledBounds(SkRect* bounds) const; | 217 SkRect styledBounds() const; |
201 | 218 |
202 /** | 219 /** |
203 * Is this shape known to be convex, before styling is applied. An unclosed
but otherwise | 220 * Is this shape known to be convex, before styling is applied. An unclosed
but otherwise |
204 * convex path is considered to be closed if they styling reflects a fill an
d not otherwise. | 221 * convex path is considered to be closed if they styling reflects a fill an
d not otherwise. |
205 * This is because filling closes all contours in the path. | 222 * This is because filling closes all contours in the path. |
206 */ | 223 */ |
207 bool knownToBeConvex() const { | 224 bool knownToBeConvex() const { |
208 switch (fType) { | 225 switch (fType) { |
209 case Type::kEmpty: | 226 case Type::kEmpty: |
210 return true; | 227 return true; |
211 case Type::kRRect: | 228 case Type::kRRect: |
212 return true; | 229 return true; |
| 230 case Type::kLine: |
| 231 return true; |
213 case Type::kPath: | 232 case Type::kPath: |
214 // SkPath.isConvex() really means "is this path convex were it t
o be closed" and | 233 // SkPath.isConvex() really means "is this path convex were it t
o be closed" and |
215 // thus doesn't give the correct answer for stroked paths, hence
we also check | 234 // thus doesn't give the correct answer for stroked paths, hence
we also check |
216 // whether the path is either filled or closed. Convex paths may
only have one | 235 // whether the path is either filled or closed. Convex paths may
only have one |
217 // contour hence isLastContourClosed() is a sufficient for a con
vex path. | 236 // contour hence isLastContourClosed() is a sufficient for a con
vex path. |
218 return (this->style().isSimpleFill() || this->path().isLastConto
urClosed()) && | 237 return (this->style().isSimpleFill() || this->path().isLastConto
urClosed()) && |
219 this->path().isConvex(); | 238 this->path().isConvex(); |
220 } | 239 } |
221 return false; | 240 return false; |
222 } | 241 } |
223 | 242 |
224 /** Is the pre-styled geometry inverse filled? */ | 243 /** Is the pre-styled geometry inverse filled? */ |
225 bool inverseFilled() const { | 244 bool inverseFilled() const { |
226 bool ret = false; | 245 bool ret = false; |
227 switch (fType) { | 246 switch (fType) { |
228 case Type::kEmpty: | 247 case Type::kEmpty: |
229 ret = false; | 248 ret = false; |
230 break; | 249 break; |
231 case Type::kRRect: | 250 case Type::kRRect: |
232 ret = fRRectData.fInverted; | 251 ret = fRRectData.fInverted; |
233 break; | 252 break; |
| 253 case Type::kLine: |
| 254 ret = fLineData.fInverted; |
| 255 break; |
234 case Type::kPath: | 256 case Type::kPath: |
235 ret = this->path().isInverseFillType(); | 257 ret = this->path().isInverseFillType(); |
236 break; | 258 break; |
237 } | 259 } |
238 // Dashing ignores inverseness. We should have caught this earlier. skbu
g.com/5421 | 260 // Dashing ignores inverseness. We should have caught this earlier. skbu
g.com/5421 |
239 SkASSERT(!(ret && this->style().isDashed())); | 261 SkASSERT(!(ret && this->style().isDashed())); |
240 return ret; | 262 return ret; |
241 } | 263 } |
242 | 264 |
243 /** | 265 /** |
(...skipping 13 matching lines...) Expand all Loading... |
257 /** | 279 /** |
258 * Is it known that the unstyled geometry has no unclosed contours. This mea
ns that it will | 280 * Is it known that the unstyled geometry has no unclosed contours. This mea
ns that it will |
259 * not have any caps if stroked (modulo the effect of any path effect). | 281 * not have any caps if stroked (modulo the effect of any path effect). |
260 */ | 282 */ |
261 bool knownToBeClosed() const { | 283 bool knownToBeClosed() const { |
262 switch (fType) { | 284 switch (fType) { |
263 case Type::kEmpty: | 285 case Type::kEmpty: |
264 return true; | 286 return true; |
265 case Type::kRRect: | 287 case Type::kRRect: |
266 return true; | 288 return true; |
| 289 case Type::kLine: |
| 290 return false; |
267 case Type::kPath: | 291 case Type::kPath: |
268 // SkPath doesn't keep track of the closed status of each contou
r. | 292 // SkPath doesn't keep track of the closed status of each contou
r. |
269 return SkPathPriv::IsClosedSingleContour(this->path()); | 293 return SkPathPriv::IsClosedSingleContour(this->path()); |
270 } | 294 } |
271 return false; | 295 return false; |
272 } | 296 } |
273 | 297 |
274 uint32_t segmentMask() const { | 298 uint32_t segmentMask() const { |
275 switch (fType) { | 299 switch (fType) { |
276 case Type::kEmpty: | 300 case Type::kEmpty: |
277 return 0; | 301 return 0; |
278 case Type::kRRect: | 302 case Type::kRRect: |
279 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) { | 303 if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) { |
280 return SkPath::kConic_SegmentMask; | 304 return SkPath::kConic_SegmentMask; |
281 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) { | 305 } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) { |
282 return SkPath::kLine_SegmentMask; | 306 return SkPath::kLine_SegmentMask; |
283 } | 307 } |
284 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask; | 308 return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask; |
| 309 case Type::kLine: |
| 310 return SkPath::kLine_SegmentMask; |
285 case Type::kPath: | 311 case Type::kPath: |
286 return this->path().getSegmentMasks(); | 312 return this->path().getSegmentMasks(); |
287 } | 313 } |
288 return 0; | 314 return 0; |
289 } | 315 } |
290 | 316 |
291 /** | 317 /** |
292 * Gets the size of the key for the shape represented by this GrShape (ignor
ing its styling). | 318 * Gets the size of the key for the shape represented by this GrShape (ignor
ing its styling). |
293 * A negative value is returned if the shape has no key (shouldn't be cached
). | 319 * A negative value is returned if the shape has no key (shouldn't be cached
). |
294 */ | 320 */ |
295 int unstyledKeySize() const; | 321 int unstyledKeySize() const; |
296 | 322 |
297 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; } | 323 bool hasUnstyledKey() const { return this->unstyledKeySize() >= 0; } |
298 | 324 |
299 /** | 325 /** |
300 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th
ere is enough | 326 * Writes unstyledKeySize() bytes into the provided pointer. Assumes that th
ere is enough |
301 * space allocated for the key and that unstyledKeySize() does not return a
negative value | 327 * space allocated for the key and that unstyledKeySize() does not return a
negative value |
302 * for this shape. | 328 * for this shape. |
303 */ | 329 */ |
304 void writeUnstyledKey(uint32_t* key) const; | 330 void writeUnstyledKey(uint32_t* key) const; |
305 | 331 |
306 private: | 332 private: |
307 enum class Type { | 333 enum class Type { |
308 kEmpty, | 334 kEmpty, |
309 kRRect, | 335 kRRect, |
| 336 kLine, |
310 kPath, | 337 kPath, |
311 }; | 338 }; |
312 | 339 |
313 void initType(Type type, const SkPath* path = nullptr) { | 340 void initType(Type type, const SkPath* path = nullptr) { |
314 fType = Type::kEmpty; | 341 fType = Type::kEmpty; |
315 this->changeType(type, path); | 342 this->changeType(type, path); |
316 } | 343 } |
317 | 344 |
318 void changeType(Type type, const SkPath* path = nullptr) { | 345 void changeType(Type type, const SkPath* path = nullptr) { |
319 bool wasPath = Type::kPath == fType; | 346 bool wasPath = Type::kPath == fType; |
(...skipping 29 matching lines...) Expand all Loading... |
349 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); | 376 GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); |
350 | 377 |
351 /** | 378 /** |
352 * Determines the key we should inherit from the input shape's geometry and
style when | 379 * Determines the key we should inherit from the input shape's geometry and
style when |
353 * we are applying the style to create a new shape. | 380 * we are applying the style to create a new shape. |
354 */ | 381 */ |
355 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc
ale); | 382 void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar sc
ale); |
356 | 383 |
357 void attemptToSimplifyPath(); | 384 void attemptToSimplifyPath(); |
358 void attemptToSimplifyRRect(); | 385 void attemptToSimplifyRRect(); |
| 386 void attemptToSimplifyLine(); |
359 | 387 |
360 // Defaults to use when there is no distinction between even/odd and winding
fills. | 388 // Defaults to use when there is no distinction between even/odd and winding
fills. |
361 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi
llType; | 389 static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_Fi
llType; |
362 static constexpr SkPath::FillType kDefaultPathInverseFillType = | 390 static constexpr SkPath::FillType kDefaultPathInverseFillType = |
363 SkPath::kInverseEvenOdd_FillType; | 391 SkPath::kInverseEvenOdd_FillType; |
364 | 392 |
365 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; | 393 static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; |
366 static constexpr unsigned kDefaultRRectStart = 0; | 394 static constexpr unsigned kDefaultRRectStart = 0; |
367 | 395 |
368 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath
Effect, | 396 static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPath
Effect, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 SkRRect fRRect; | 441 SkRRect fRRect; |
414 SkPath::Direction fDir; | 442 SkPath::Direction fDir; |
415 unsigned fStart; | 443 unsigned fStart; |
416 bool fInverted; | 444 bool fInverted; |
417 } fRRectData; | 445 } fRRectData; |
418 struct { | 446 struct { |
419 SkPath fPath; | 447 SkPath fPath; |
420 // Gen ID of the original path (fPath may be modified) | 448 // Gen ID of the original path (fPath may be modified) |
421 int32_t fGenID; | 449 int32_t fGenID; |
422 } fPathData; | 450 } fPathData; |
| 451 struct { |
| 452 SkPoint fPts[2]; |
| 453 bool fInverted; |
| 454 } fLineData; |
423 }; | 455 }; |
424 GrStyle fStyle; | 456 GrStyle fStyle; |
425 SkAutoSTArray<8, uint32_t> fInheritedKey; | 457 SkAutoSTArray<8, uint32_t> fInheritedKey; |
426 }; | 458 }; |
427 #endif | 459 #endif |
OLD | NEW |