aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-09-01 09:00:45 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-01 15:31:37 +0000
commit4f40caf33e15c4e2e21742854dfd5cfd31812c3f (patch)
tree626b1e828cb840095368e4f1ec4427ca06753d53 /src
parent867017de0cd9d2104a291ddd6d6eef808edd82b6 (diff)
Add methods for converting GrShape to filled style
Bug: skia: Change-Id: I6726428d1358909972adec8d63686b637ef5bb5e Reviewed-on: https://skia-review.googlesource.com/40222 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrShape.cpp78
-rw-r--r--src/gpu/GrShape.h22
2 files changed, 98 insertions, 2 deletions
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp
index 221247808b..4691ede621 100644
--- a/src/gpu/GrShape.cpp
+++ b/src/gpu/GrShape.cpp
@@ -31,6 +31,82 @@ GrShape& GrShape::operator=(const GrShape& that) {
return *this;
}
+static bool flip_inversion(bool originalIsInverted, GrShape::FillInversion inversion) {
+ switch (inversion) {
+ case GrShape::FillInversion::kPreserve:
+ return false;
+ case GrShape::FillInversion::kFlip:
+ return true;
+ case GrShape::FillInversion::kForceInverted:
+ return !originalIsInverted;
+ case GrShape::FillInversion::kForceNoninverted:
+ return originalIsInverted;
+ }
+ return false;
+}
+
+static bool is_inverted(bool originalIsInverted, GrShape::FillInversion inversion) {
+ switch (inversion) {
+ case GrShape::FillInversion::kPreserve:
+ return originalIsInverted;
+ case GrShape::FillInversion::kFlip:
+ return !originalIsInverted;
+ case GrShape::FillInversion::kForceInverted:
+ return true;
+ case GrShape::FillInversion::kForceNoninverted:
+ return false;
+ }
+ return false;
+}
+
+GrShape GrShape::MakeFilled(const GrShape& original, FillInversion inversion) {
+ if (original.style().isSimpleFill() && !flip_inversion(original.inverseFilled(), inversion)) {
+ // By returning the original rather than falling through we can preserve any inherited style
+ // key. Otherwise, we wipe it out below since the style change invalidates it.
+ return original;
+ }
+ GrShape result;
+ switch (original.fType) {
+ case Type::kRRect:
+ result.fType = original.fType;
+ result.fRRectData.fRRect = original.fRRectData.fRRect;
+ result.fRRectData.fDir = kDefaultRRectDir;
+ result.fRRectData.fStart = kDefaultRRectStart;
+ result.fRRectData.fInverted = is_inverted(original.fRRectData.fInverted, inversion);
+ break;
+ case Type::kLine:
+ // Lines don't fill.
+ if (is_inverted(original.fLineData.fInverted, inversion)) {
+ result.fType = Type::kInvertedEmpty;
+ } else {
+ result.fType = Type::kEmpty;
+ }
+ break;
+ case Type::kEmpty:
+ result.fType = is_inverted(false, inversion) ? Type::kInvertedEmpty : Type::kEmpty;
+ break;
+ case Type::kInvertedEmpty:
+ result.fType = is_inverted(true, inversion) ? Type::kInvertedEmpty : Type::kEmpty;
+ break;
+ case Type::kPath:
+ result.initType(Type::kPath, &original.fPathData.fPath);
+ result.fPathData.fGenID = original.fPathData.fGenID;
+ if (flip_inversion(original.fPathData.fPath.isInverseFillType(), inversion)) {
+ result.fPathData.fPath.toggleInverseFillType();
+ }
+ if (!original.style().isSimpleFill()) {
+ // Going from a non-filled style to fill may allow additional simplifications (e.g.
+ // closing an open rect that wasn't closed in the original shape because it had
+ // stroke style).
+ result.attemptToSimplifyPath();
+ }
+ break;
+ }
+ // We don't copy the inherited key since it can contain path effect information that we just
+ // stripped.
+ return result;
+}
+
SkRect GrShape::bounds() const {
// Bounds where left == bottom or top == right can indicate a line or point shape. We return
// inverted bounds for a truly empty shape.
@@ -206,7 +282,7 @@ void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca
// We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key as
// ApplyFullStyle(shape).
// The full key is structured as (geo,path_effect,stroke).
- // If we do ApplyPathEffect we get get,path_effect as the inherited key. If we then
+ // If we do ApplyPathEffect we get geo,path_effect as the inherited key. If we then
// do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited key
// and then append the style key (which should now be stroke only) at the end.
int parentCnt = parent.fInheritedKey.count();
diff --git a/src/gpu/GrShape.h b/src/gpu/GrShape.h
index 5226c239cd..2b48eca633 100644
--- a/src/gpu/GrShape.h
+++ b/src/gpu/GrShape.h
@@ -30,7 +30,7 @@
*
* 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.
+ * that have fast paths in the GPU backend.
*/
class GrShape {
public:
@@ -121,6 +121,25 @@ public:
~GrShape() { this->changeType(Type::kEmpty); }
+ /**
+ * Informs MakeFilled on how to modify that shape's fill rule when making a simple filled
+ * version of the shape.
+ */
+ enum class FillInversion {
+ kPreserve,
+ kFlip,
+ kForceNoninverted,
+ kForceInverted
+ };
+ /**
+ * Makes a filled shape from the pre-styled original shape and optionally modifies whether
+ * the fill is inverted or not. It's important to note that the original shape's geometry
+ * may already have been modified if doing so was neutral with respect to its style
+ * (e.g. filled paths are always closed when stored in a shape and dashed paths are always
+ * made non-inverted since dashing ignores inverseness).
+ */
+ static GrShape MakeFilled(const GrShape& original, FillInversion = FillInversion::kPreserve);
+
const GrStyle& style() const { return fStyle; }
/**
@@ -347,6 +366,7 @@ public:
void writeUnstyledKey(uint32_t* key) const;
private:
+
enum class Type {
kEmpty,
kInvertedEmpty,