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