Bug 1181554 - Snap the spread radius for inset box shadows to device pixels. r=jrmuizel, a=lmandel
authorMarkus Stange <mstange@themasta.com>
Fri, 17 Jul 2015 14:42:44 -0400
changeset 268959 b69bdd81e1cdc53c3d547c56ba2bd64dffe56346
parent 268958 0d42bfee9ce7b0f79764dd5eb1cebdffdc168a5f
child 268960 2a8f562a88060d00295cbdcb68c37742cd01bc67
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, lmandel
bugs1181554
milestone41.0a2
Bug 1181554 - Snap the spread radius for inset box shadows to device pixels. r=jrmuizel, a=lmandel
layout/base/nsCSSRendering.cpp
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1510,24 +1510,37 @@ nsCSSRendering::PaintBoxShadowInner(nsPr
     // shadowClipRect: the area on the temporary surface within shadowPaintRect
     //                 that we will NOT paint in
     nscoord blurRadius = shadowItem->mRadius;
     nsMargin blurMargin =
       nsContextBoxBlur::GetBlurRadiusMargin(blurRadius, twipsPerPixel);
     nsRect shadowPaintRect = paddingRect;
     shadowPaintRect.Inflate(blurMargin);
 
+    Rect shadowPaintGfxRect = NSRectToRect(shadowPaintRect, twipsPerPixel);
+    shadowPaintGfxRect.RoundOut();
+
+    // Round the spread radius to device pixels (by truncation).
+    // This mostly matches what we do for borders, except that we don't round
+    // up values between zero and one device pixels to one device pixel.
+    // This way of rounding is symmetric around zero, which makes sense for
+    // the spread radius.
+    int32_t spreadDistance = shadowItem->mSpread / twipsPerPixel;
+    nscoord spreadDistanceAppUnits = aPresContext->DevPixelsToAppUnits(spreadDistance);
+
     nsRect shadowClipRect = paddingRect;
     shadowClipRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset);
-    shadowClipRect.Deflate(shadowItem->mSpread, shadowItem->mSpread);
+    shadowClipRect.Deflate(spreadDistanceAppUnits, spreadDistanceAppUnits);
+
+    Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, twipsPerPixel);
+    shadowClipGfxRect.Round();
 
     RectCornerRadii clipRectRadii;
     if (hasBorderRadius) {
       // Calculate the radii the inner clipping rect will have
-      Float spreadDistance = shadowItem->mSpread / twipsPerPixel;
       Float borderSizes[4] = {0, 0, 0, 0};
 
       // See PaintBoxShadowOuter and bug 514670
       if (innerRadii[C_TL].width > 0 || innerRadii[C_BL].width > 0) {
         borderSizes[NS_SIDE_LEFT] = spreadDistance;
       }
 
       if (innerRadii[C_TL].height > 0 || innerRadii[C_TR].height > 0) {
@@ -1592,20 +1605,16 @@ nsCSSRendering::PaintBoxShadowInner(nsPr
         MakePathForRoundedRect(*drawTarget, shadowGfxRect, innerRadii);
       renderContext->Clip(roundedRect);
     } else {
       renderContext->Clip(shadowGfxRect);
     }
 
     // Fill the surface minus the area within the frame that we should
     // not paint in, and blur and apply it.
-    Rect shadowPaintGfxRect = NSRectToRect(shadowPaintRect, twipsPerPixel);
-    shadowPaintGfxRect.RoundOut();
-    Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, twipsPerPixel);
-    shadowClipGfxRect.Round();
     RefPtr<PathBuilder> builder =
       shadowDT->CreatePathBuilder(FillRule::FILL_EVEN_ODD);
     AppendRectToPath(builder, shadowPaintGfxRect, true);
     if (hasBorderRadius) {
       AppendRoundedRectToPath(builder, shadowClipGfxRect, clipRectRadii, false);
     } else {
       AppendRectToPath(builder, shadowClipGfxRect, false);
     }