Fix reflected ovals.
authorJim Van Verth <jvanverth@google.com>
Thu, 20 Apr 2017 21:25:26 +0000 (17:25 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 21 Apr 2017 13:28:45 +0000 (13:28 +0000)
Addresses an issue with ovals transformed by a matrix with a reflection.
Also adds a further check for circles to ensure that teeny tiny ovals
(sizes < SK_ScalarNearlyZero) aren't treated as circles.

Change-Id: Ie50e4a98365eba7c23e53e68886ebac981ed1def
Reviewed-on: https://skia-review.googlesource.com/13989
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>

gm/ovals.cpp
src/gpu/ops/GrOvalOpFactory.cpp

index ec9bd75..d6afdcb 100644 (file)
@@ -268,6 +268,26 @@ protected:
 
             canvas->restore();
         }
+
+        // reflected oval
+        for (int i = 0; i < fPaints.count(); ++i) {
+            SkRect oval = SkRect::MakeLTRB(-30, -30, 30, 30);
+            canvas->save();
+            // position the oval, and make it at off-integer coords.
+            canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
+                              kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
+                              SK_ScalarHalf * kYStep);
+            canvas->rotate(90);
+            canvas->scale(1, -1);
+            canvas->scale(1, 0.66f);
+
+            SkColor color = genColor(&rand);
+            fPaints[i].setColor(color);
+
+            canvas->drawRect(oval, rectPaint);
+            canvas->drawOval(oval, fPaints[i]);
+            canvas->restore();
+        }
     }
 
 private:
index e00ee0b..71f8bb0 100644 (file)
@@ -1172,8 +1172,8 @@ public:
         SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
         SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
         SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX] * ellipseXRadius +
-                                       viewMatrix[SkMatrix::kMSkewY] * ellipseYRadius);
-        SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX] * ellipseXRadius +
+                                       viewMatrix[SkMatrix::kMSkewX] * ellipseYRadius);
+        SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewY] * ellipseXRadius +
                                        viewMatrix[SkMatrix::kMScaleY] * ellipseYRadius);
 
         // do (potentially) anisotropic mapping of stroke
@@ -2385,7 +2385,8 @@ std::unique_ptr<GrLegacyMeshDrawOp> GrOvalOpFactory::MakeOvalOp(GrColor color,
                                                                 const GrShaderCaps* shaderCaps) {
     // we can draw circles
     SkScalar width = oval.width();
-    if (SkScalarNearlyEqual(width, oval.height()) && circle_stays_circle(viewMatrix)) {
+    if (width > SK_ScalarNearlyZero && SkScalarNearlyEqual(width, oval.height()) &&
+        circle_stays_circle(viewMatrix)) {
         SkPoint center = {oval.centerX(), oval.centerY()};
         return CircleOp::Make(color, viewMatrix, center, width / 2.f, GrStyle(stroke, nullptr));
     }