Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: src/gpu/GrShape.h

Issue 2042813002: Make GrShape track the winding direction and starting point for rrect types. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: minor Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkRRect.h ('k') | src/gpu/GrShape.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrShape.h
diff --git a/src/gpu/GrShape.h b/src/gpu/GrShape.h
index 12093f41436e492dbb9af9d0de61abdb5548f032..1728b3b2f14ed17820d96722855f9a8ca532a666 100644
--- a/src/gpu/GrShape.h
+++ b/src/gpu/GrShape.h
@@ -10,6 +10,7 @@
#include "GrStyle.h"
#include "SkPath.h"
+#include "SkPathPriv.h"
#include "SkRRect.h"
#include "SkTemplates.h"
#include "SkTLazy.h"
@@ -27,29 +28,33 @@
* to two shapes that reflect the same underlying geometry the computed keys of the stylized shapes
* will be the same.
*
- * Currently this can only be constructed from a rrect, though it can become a path by applying
- * style to the geometry. The idea is to expand this to cover most or all of the geometries that
- * have SkCanvas::draw APIs.
+ * Currently this can only be constructed from a path, rect, or rrect though it can become a path
+ * applying style to the geometry. The idea is to expand this to cover most or all of the geometries
+ * that have SkCanvas::draw APIs.
*/
class GrShape {
public:
GrShape() : fType(Type::kEmpty) {}
explicit GrShape(const SkPath& path)
- : fType(Type::kPath)
- , fPath(&path) {
+ : fType(Type::kPath)
+ , fPath(&path) {
this->attemptToReduceFromPath();
}
explicit GrShape(const SkRRect& rrect)
: fType(Type::kRRect)
- , fRRect(rrect) {
+ , fRRect(rrect)
+ , fRRectDir(SkPath::kCW_Direction)
+ , fRRectStart(DefaultRRectStartIndex(rrect, false)) {
this->attemptToReduceFromRRect();
}
explicit GrShape(const SkRect& rect)
: fType(Type::kRRect)
- , fRRect(SkRRect::MakeRect(rect)) {
+ , fRRect(SkRRect::MakeRect(rect))
+ , fRRectDir(SkPath::kCW_Direction)
+ , fRRectStart(1) {
this->attemptToReduceFromRRect();
}
@@ -63,7 +68,23 @@ public:
GrShape(const SkRRect& rrect, const GrStyle& style)
: fType(Type::kRRect)
, fRRect(rrect)
+ , fRRectDir(SkPath::kCW_Direction)
+ , fRRectStart(DefaultRRectStartIndex(rrect, SkToBool(style.pathEffect())))
+ , fStyle(style) {
+ this->attemptToReduceFromRRect();
+ }
+
+ GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, const GrStyle& style)
+ : fType(Type::kRRect)
+ , fRRect(rrect)
, fStyle(style) {
+ if (style.pathEffect()) {
+ fRRectDir = dir;
+ fRRectStart = start;
+ } else {
+ fRRectDir = SkPath::kCW_Direction;
+ fRRectStart = DefaultRRectStartIndex(rrect, false);
+ }
this->attemptToReduceFromRRect();
}
@@ -71,6 +92,7 @@ public:
: fType(Type::kRRect)
, fRRect(SkRRect::MakeRect(rect))
, fStyle(style) {
+ fRRectStart = DefaultRectDirAndStartIndex(rect, style.pathEffect(), &fRRectDir);
this->attemptToReduceFromRRect();
}
@@ -84,7 +106,9 @@ public:
GrShape(const SkRRect& rrect, const SkPaint& paint)
: fType(Type::kRRect)
, fRRect(rrect)
+ , fRRectDir(SkPath::kCW_Direction)
, fStyle(paint) {
+ fRRectStart = DefaultRRectStartIndex(rrect, SkToBool(fStyle.pathEffect()));
this->attemptToReduceFromRRect();
}
@@ -92,6 +116,7 @@ public:
: fType(Type::kRRect)
, fRRect(SkRRect::MakeRect(rect))
, fStyle(paint) {
+ fRRectStart = DefaultRectDirAndStartIndex(rect, fStyle.pathEffect(), &fRRectDir);
this->attemptToReduceFromRRect();
}
@@ -116,13 +141,19 @@ public:
}
/** Returns the unstyled geometry as a rrect if possible. */
- bool asRRect(SkRRect* rrect) const {
+ bool asRRect(SkRRect* rrect, SkPath::Direction* dir, unsigned* start) const {
if (Type::kRRect != fType) {
return false;
}
if (rrect) {
*rrect = fRRect;
}
+ if (dir) {
+ *dir = fRRectDir;
+ }
+ if (start) {
+ *start = fRRectStart;
+ }
return true;
}
@@ -134,7 +165,7 @@ public:
break;
case Type::kRRect:
out->reset();
- out->addRRect(fRRect);
+ out->addRRect(fRRect, fRRectDir, fRRectStart);
break;
case Type::kPath:
*out = *fPath.get();
@@ -190,7 +221,6 @@ private:
kPath,
};
-
/** Constructor used by the applyStyle() function */
GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale);
@@ -202,8 +232,8 @@ private:
void attemptToReduceFromPath() {
SkASSERT(Type::kPath == fType);
- fType = AttemptToReduceFromPathImpl(*fPath.get(), &fRRect, fStyle.pathEffect(),
- fStyle.strokeRec());
+ fType = AttemptToReduceFromPathImpl(*fPath.get(), &fRRect, &fRRectDir, &fRRectStart,
+ fStyle.pathEffect(), fStyle.strokeRec());
if (Type::kPath != fType) {
fPath.reset();
fInheritedKey.reset(0);
@@ -219,31 +249,62 @@ private:
}
static Type AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect,
- const SkPathEffect* pe, const SkStrokeRec& strokeRec) {
- if (path.isEmpty()) {
- return Type::kEmpty;
- }
- if (path.isRRect(rrect)) {
- SkASSERT(!rrect->isEmpty());
- return Type::kRRect;
+ SkPath::Direction* rrectDir, unsigned* rrectStart,
+ const SkPathEffect* pe, const SkStrokeRec& strokeRec);
+
+ static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPathEffect,
+ SkPath::Direction* dir) {
+ // This is the default direction when a rect is added to a path.
+ *dir = SkPath::kCW_Direction;
+ // This comes from SkPath's interface. The default for adding a SkRect is counter clockwise
+ // beginning at index 0 (which happens to correspond to rrect index 0 or 7).
+ if (!hasPathEffect) {
+ return 0;
}
- SkRect rect;
- if (path.isOval(&rect)) {
- rrect->setOval(rect);
- return Type::kRRect;
+ // We store rects as rrects. RRects don't preserve the invertedness, but rather sort the
+ // rect edges. Thus, we may need to modify the rrect's start index to account for the sort.
+ *dir = SkPath::kCW_Direction;
egdaniel 2016/06/06 15:50:29 This line is repeated above
bsalomon 2016/06/06 16:28:05 Done.
+ bool swapX = rect.fLeft > rect.fRight;
+ bool swapY = rect.fTop > rect.fBottom;
+ if (swapX && swapY) {
+ // 0 becomes start index 2 and times 2 to convert from rect the rrect indices.
+ return 2 * 2;
+ } else if (swapX) {
+ *dir = SkPath::kCW_Direction;
egdaniel 2016/06/06 15:50:29 CCW?
bsalomon 2016/06/06 16:28:04 Done.
+ // 0 becomes start index 1 and times 2 to convert from rect the rrect indices.
+ return 2 * 1;
+ } else if (swapY) {
+ *dir = SkPath::kCW_Direction;
egdaniel 2016/06/06 15:50:29 CCW?
bsalomon 2016/06/06 16:28:05 Done.
+ // 0 becomes start index 3 and times 2 to convert from rect the rrect indices.
+ return 2 * 3;
}
- bool closed;
- if (path.isRect(&rect, &closed, nullptr)) {
- if (closed || (!pe && strokeRec.isFillStyle())) {
- rrect->setRect(rect);
- return Type::kRRect;
+ return 0;
+ }
+
+ static unsigned DefaultRRectStartIndex(const SkRRect& rrect, bool hasPathEffect) {
+ // This comes from SkPath's interface. The default for adding a SkRRect to a path is
+ // clockwise beginning at starting index 6.
+ static constexpr unsigned kDefaultRRectStartIdx = 6;
+ if (!hasPathEffect) {
+ // Rect and Oval subtypes have their own default/canonical starting index. This agrees
+ // with AttemptToReduceFromPathImpl and SkPath's add[Oval Rect] methods.
+ if (rrect.getType() == SkRRect::kRect_Type) {
+ // The default rect starting point in SkPath::addRect is 0 which stays 0
+ // in terms of rrect indices.
+ return 0;
+ } else if (rrect.getType() == SkRRect::kOval_Type) {
+ // The default oval starting point in SkPath::addOval is 1 which converts to 2
+ // in terms of rrect indices.
+ return 2;
}
}
- return Type::kPath;
+ return kDefaultRRectStartIdx;
}
Type fType;
SkRRect fRRect;
+ SkPath::Direction fRRectDir;
+ unsigned fRRectStart;
SkTLazy<SkPath> fPath;
GrStyle fStyle;
SkAutoSTArray<8, uint32_t> fInheritedKey;
« no previous file with comments | « include/core/SkRRect.h ('k') | src/gpu/GrShape.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698