aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrShape.cpp
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-06-28 11:56:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-28 11:56:42 -0700
commit0a0f67ececbdf1a7f81296ed0d2cb9e3bc00e4dc (patch)
treef49e73525e56c6e6d0dcfc68f1eeba895920137b /src/gpu/GrShape.cpp
parent635df95a9a25c66959f76b4bbb594b75333ded21 (diff)
Make lines a special case in GrShape
Diffstat (limited to 'src/gpu/GrShape.cpp')
-rw-r--r--src/gpu/GrShape.cpp89
1 files changed, 69 insertions, 20 deletions
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp
index 45ddb77778..5ffd32d46d 100644
--- a/src/gpu/GrShape.cpp
+++ b/src/gpu/GrShape.cpp
@@ -14,10 +14,10 @@ GrShape& GrShape::operator=(const GrShape& that) {
case Type::kEmpty:
break;
case Type::kRRect:
- fRRectData.fRRect = that.fRRectData.fRRect;
- fRRectData.fDir = that.fRRectData.fDir;
- fRRectData.fStart = that.fRRectData.fStart;
- fRRectData.fInverted = that.fRRectData.fInverted;
+ fRRectData = that.fRRectData;
+ break;
+ case Type::kLine:
+ fLineData = that.fLineData;
break;
case Type::kPath:
fPathData.fGenID = that.fPathData.fGenID;
@@ -29,11 +29,29 @@ GrShape& GrShape::operator=(const GrShape& that) {
return *this;
}
-const SkRect& GrShape::bounds() const {
+SkRect GrShape::bounds() const {
static constexpr SkRect kEmpty = SkRect::MakeEmpty();
switch (fType) {
case Type::kEmpty:
return kEmpty;
+ case Type::kLine: {
+ SkRect bounds;
+ if (fLineData.fPts[0].fX < fLineData.fPts[1].fX) {
+ bounds.fLeft = fLineData.fPts[0].fX;
+ bounds.fRight = fLineData.fPts[1].fX;
+ } else {
+ bounds.fLeft = fLineData.fPts[1].fX;
+ bounds.fRight = fLineData.fPts[0].fX;
+ }
+ if (fLineData.fPts[0].fY < fLineData.fPts[1].fY) {
+ bounds.fTop = fLineData.fPts[0].fY;
+ bounds.fBottom = fLineData.fPts[1].fY;
+ } else {
+ bounds.fTop = fLineData.fPts[1].fY;
+ bounds.fBottom = fLineData.fPts[0].fY;
+ }
+ return bounds;
+ }
case Type::kRRect:
return fRRectData.fRRect.getBounds();
case Type::kPath:
@@ -43,12 +61,13 @@ const SkRect& GrShape::bounds() const {
return kEmpty;
}
-void GrShape::styledBounds(SkRect* bounds) const {
+SkRect GrShape::styledBounds() const {
if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) {
- *bounds = SkRect::MakeEmpty();
- } else {
- fStyle.adjustBounds(bounds, this->bounds());
+ return SkRect::MakeEmpty();
}
+ SkRect bounds;
+ fStyle.adjustBounds(&bounds, this->bounds());
+ return bounds;
}
int GrShape::unstyledKeySize() const {
@@ -63,6 +82,10 @@ int GrShape::unstyledKeySize() const {
SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
// + 1 for the direction, start index, and inverseness.
return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
+ case Type::kLine:
+ GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint));
+ // 4 for the end points and 1 for the inverseness
+ return 5;
case Type::kPath:
if (0 == fPathData.fGenID) {
return -1;
@@ -94,6 +117,11 @@ void GrShape::writeUnstyledKey(uint32_t* key) const {
*key++ |= fRRectData.fStart;
SkASSERT(fRRectData.fStart < 8);
break;
+ case Type::kLine:
+ memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint));
+ key += 4;
+ *key++ = fLineData.fInverted ? 1 : 0;
+ break;
case Type::kPath:
SkASSERT(fPathData.fGenID);
*key++ = fPathData.fGenID;
@@ -159,10 +187,10 @@ GrShape::GrShape(const GrShape& that) : fStyle(that.fStyle) {
case Type::kEmpty:
break;
case Type::kRRect:
- fRRectData.fRRect = that.fRRectData.fRRect;
- fRRectData.fDir = that.fRRectData.fDir;
- fRRectData.fStart = that.fRRectData.fStart;
- fRRectData.fInverted = that.fRRectData.fInverted;
+ fRRectData = that.fRRectData;
+ break;
+ case Type::kLine:
+ fLineData = that.fLineData;
break;
case Type::kPath:
fPathData.fGenID = that.fPathData.fGenID;
@@ -266,8 +294,14 @@ void GrShape::attemptToSimplifyPath() {
SkPath::Direction rrectDir;
unsigned rrectStart;
bool inverted = this->path().isInverseFillType();
+ SkPoint pts[2];
if (this->path().isEmpty()) {
this->changeType(Type::kEmpty);
+ } else if (this->path().isLine(pts)) {
+ this->changeType(Type::kLine);
+ fLineData.fPts[0] = pts[0];
+ fLineData.fPts[1] = pts[1];
+ fLineData.fInverted = inverted;
} else if (this->path().isRRect(&rrect, &rrectDir, &rrectStart)) {
this->changeType(Type::kRRect);
fRRectData.fRRect = rrect;
@@ -313,6 +347,8 @@ void GrShape::attemptToSimplifyPath() {
fInheritedKey.reset(0);
if (Type::kRRect == fType) {
this->attemptToSimplifyRRect();
+ } else if (Type::kLine == fType) {
+ this->attemptToSimplifyLine();
}
} else {
if (fInheritedKey.count() || this->path().isVolatile()) {
@@ -321,13 +357,8 @@ void GrShape::attemptToSimplifyPath() {
fPathData.fGenID = this->path().getGenerationID();
}
if (this->style().isSimpleFill()) {
- // Filled paths are treated as though all their contours were closed.
- // Since SkPath doesn't track individual contours, this will only close the last. :(
- // There is no point in closing lines, though, since they loose their line-ness.
- if (!this->path().isLine(nullptr)) {
- this->path().close();
- this->path().setIsVolatile(true);
- }
+ this->path().close();
+ this->path().setIsVolatile(true);
}
if (!this->style().hasNonDashPathEffect()) {
if (this->style().strokeRec().getStyle() == SkStrokeRec::kStroke_Style ||
@@ -368,3 +399,21 @@ void GrShape::attemptToSimplifyRRect() {
fRRectData.fInverted = false;
}
}
+
+void GrShape::attemptToSimplifyLine() {
+ if (fStyle.isSimpleFill() && !fLineData.fInverted) {
+ this->changeType(Type::kEmpty);
+ } else {
+ // Only path effects could care about the order of the points. Otherwise canonicalize
+ // the point order
+ if (!fStyle.hasPathEffect()) {
+ SkPoint* pts = fLineData.fPts;
+ if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].fX)) {
+ SkTSwap(pts[0], pts[1]);
+ }
+ } else if (fStyle.isDashed()) {
+ // Dashing ignores inverseness.
+ fLineData.fInverted = false;
+ }
+ }
+}