Fix non-uniform scale and stroked ellipses
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 19 Apr 2013 19:01:45 +0000 (19:01 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 19 Apr 2013 19:01:45 +0000 (19:01 +0000)
Strokes were not being scaled properly for ellipses -- the
view matrix was being reset before the scale factors were
being applied. Scaling the stroke has been moved up higher in
the process. Also applies some optimizations suggested by
robertphillips.

R=robertphillips@google.com

Author: jvanverth@google.com

Review URL: https://chromiumcodereview.appspot.com/14017012

git-svn-id: http://skia.googlecode.com/svn/trunk@8777 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/GrOvalRenderer.cpp

index 42fb2b7..3ecd302 100644 (file)
@@ -420,17 +420,26 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     }
 #endif
 
+    // do any matrix crunching before we reset the draw state for device coords
     const SkMatrix& vm = drawState->getViewMatrix();
     GrPoint center = GrPoint::Make(ellipse.centerX(), ellipse.centerY());
     vm.mapPoints(&center, 1);
-    SkRect xformedRect;
-    vm.mapRect(&xformedRect, ellipse);
-    SkScalar xRadius = SkScalarHalf(xformedRect.width());
-    SkScalar yRadius = SkScalarHalf(xformedRect.height());
+    SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
+    SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
+    SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*ellipseXRadius + 
+                                   vm[SkMatrix::kMSkewY]*ellipseYRadius);
+    SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*ellipseXRadius + 
+                                   vm[SkMatrix::kMScaleY]*ellipseYRadius);
     if (SkScalarDiv(xRadius, yRadius) > 2 || SkScalarDiv(yRadius, xRadius) > 2) {
         return false;
     }
 
+    // do (potentially) anisotropic mapping of stroke
+    SkVector scaledStroke;
+    SkScalar strokeWidth = stroke.getWidth();
+    scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] + vm[SkMatrix::kMSkewY]));
+    scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] + vm[SkMatrix::kMScaleY]));
+
     GrDrawState::AutoDeviceCoordDraw adcd(drawState);
     if (!adcd.succeeded()) {
         return false;
@@ -472,12 +481,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
     SkScalar innerRatio = 1.0f;
 
     if (SkStrokeRec::kFill_Style != style) {
-        SkScalar strokeWidth = stroke.getWidth();
 
-        // do (potentially) anisotropic mapping
-        SkVector scaledStroke;
-        scaledStroke.set(strokeWidth, strokeWidth);
-        vm.mapVectors(&scaledStroke, 1);
 
         if (SkScalarNearlyZero(scaledStroke.length())) {
             scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);