Add drawRRect and drawShape(GrShape) to GrSWMaskHelper

Change-Id: I68d586b44f3207c330e5c0505659457c9d05074e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287384
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 840396b..0ccec74 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -33,21 +33,34 @@
     return modeMap[op];
 }
 
+static SkPaint get_paint(SkRegion::Op op, GrAA aa, uint8_t alpha) {
+    SkPaint paint;
+    paint.setBlendMode(op_to_mode(op));
+    paint.setAntiAlias(GrAA::kYes == aa);
+    // SkPaint's color is unpremul so this will produce alpha in every channel.
+    paint.setColor(SkColorSetARGB(alpha, 255, 255, 255));
+    return paint;
+}
+
 /**
  * Draw a single rect element of the clip stack into the accumulation bitmap
  */
 void GrSWMaskHelper::drawRect(const SkRect& rect, const SkMatrix& matrix, SkRegion::Op op, GrAA aa,
                               uint8_t alpha) {
-    SkPaint paint;
-    paint.setBlendMode(op_to_mode(op));
-    paint.setAntiAlias(GrAA::kYes == aa);
-    paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
-
     SkMatrix translatedMatrix = matrix;
     translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
     fDraw.fMatrix = &translatedMatrix;
 
-    fDraw.drawRect(rect, paint);
+    fDraw.drawRect(rect, get_paint(op, aa, alpha));
+}
+
+void GrSWMaskHelper::drawRRect(const SkRRect& rrect, const SkMatrix& matrix, SkRegion::Op op,
+                               GrAA aa, uint8_t alpha) {
+    SkMatrix translatedMatrix = matrix;
+    translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
+    fDraw.fMatrix = &translatedMatrix;
+
+    fDraw.drawRRect(rrect, get_paint(op, aa, alpha));
 }
 
 /**
@@ -55,10 +68,9 @@
  */
 void GrSWMaskHelper::drawShape(const GrStyledShape& shape, const SkMatrix& matrix, SkRegion::Op op,
                                GrAA aa, uint8_t alpha) {
-    SkPaint paint;
+    SkPaint paint = get_paint(op, aa, alpha);
     paint.setPathEffect(shape.style().refPathEffect());
     shape.style().strokeRec().applyToPaint(&paint);
-    paint.setAntiAlias(GrAA::kYes == aa);
 
     SkMatrix translatedMatrix = matrix;
     translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
@@ -70,11 +82,46 @@
         SkASSERT(0xFF == paint.getAlpha());
         fDraw.drawPathCoverage(path, paint);
     } else {
-        paint.setBlendMode(op_to_mode(op));
-        paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
         fDraw.drawPath(path, paint);
     }
-};
+}
+
+void GrSWMaskHelper::drawShape(const GrShape& shape, const SkMatrix& matrix, SkRegion::Op op,
+                               GrAA aa, uint8_t alpha) {
+    SkPaint paint = get_paint(op, aa, alpha);
+
+    SkMatrix translatedMatrix = matrix;
+    translatedMatrix.postTranslate(fTranslate.fX, fTranslate.fY);
+    fDraw.fMatrix = &translatedMatrix;
+
+    if (shape.inverted()) {
+        if (shape.isEmpty() || shape.isLine() || shape.isPoint()) {
+            // These shapes are empty for simple fills, so when inverted, cover everything
+            fDraw.drawPaint(paint);
+            return;
+        }
+        // Else fall through to the draw method using asPath(), which will toggle fill type properly
+    } else if (shape.isEmpty() || shape.isLine() || shape.isPoint()) {
+        // Do nothing, these shapes do not cover any pixels for simple fills
+        return;
+    } else if (shape.isRect()) {
+        fDraw.drawRect(shape.rect(), paint);
+        return;
+    } else if (shape.isRRect()) {
+        fDraw.drawRRect(shape.rrect(), paint);
+        return;
+    }
+
+    // A complex, or inverse-filled shape, so go through drawPath.
+    SkPath path;
+    shape.asPath(&path);
+    if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
+        SkASSERT(0xFF == paint.getAlpha());
+        fDraw.drawPathCoverage(path, paint);
+    } else {
+        fDraw.drawPath(path, paint);
+    }
+}
 
 bool GrSWMaskHelper::init(const SkIRect& resultBounds) {
     // We will need to translate draws so the bound's UL corner is at the origin