Bug 1346618 - Part 1. Correct opacity pass to VectorImage. draft
authorcku <cku@mozilla.com>
Sat, 18 Mar 2017 00:13:08 +0800
changeset 500757 e84263ec74216ba159b41d2eba62d3f5526cba09
parent 500720 9a95ade0ec97a871f97c397261fc7297e897331f
child 500758 6082ed69ca700d6f2071e01158e476b7fb278c0c
push id49789
push userbmo:cku@mozilla.com
push dateFri, 17 Mar 2017 16:29:52 +0000
bugs1346618
milestone55.0a1
Bug 1346618 - Part 1. Correct opacity pass to VectorImage. Even we pass aOpacity(0.5) to an SVGDrawingParameters object's constructor at [1], SVGDrawingParameters::opacity will still be set as 1.0 since we also pass aSVGContext to it. As a result, SVGDrawingParameters::opacity is set by the return value of aSVGContext->GetGlobalOpacity(), which is 1.0. I tried to fix this problem by pass opacity to SVGImageContext. [1] https://hg.mozilla.org/mozilla-central/file/588c44c7a966/image/VectorImage.cpp#l789 MozReview-Commit-ID: ByiPa4sreEh
layout/base/nsLayoutUtils.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6572,16 +6572,21 @@ DrawImageInternal(gfxContext&           
                   const nsRect&          aFill,
                   const nsPoint&         aAnchor,
                   const nsRect&          aDirty,
                   const Maybe<SVGImageContext>& aSVGContext,
                   uint32_t               aImageFlags,
                   ExtendMode             aExtendMode = ExtendMode::CLAMP,
                   float                  aOpacity = 1.0)
 {
+  // The opacity value of aSVGContext, SVGImageContext::GetGlobalOpacity(),
+  // will be used and aOpacity will be discard by passing valid aSVGContext.
+  // Do not pass the opacity value via aOpacity in this case.
+  MOZ_ASSERT_IF(aSVGContext, aOpacity == 1.0);
+
   DrawResult result = DrawResult::SUCCESS;
 
   aImageFlags |= imgIContainer::FLAG_ASYNC_NOTIFY;
 
   if (aPresContext->Type() == nsPresContext::eContext_Print) {
     // We want vector images to be passed on as vector commands, not a raster
     // image.
     aImageFlags |= imgIContainer::FLAG_BYPASS_SURFACE_CACHE;
@@ -6791,36 +6796,36 @@ nsLayoutUtils::DrawBackgroundImage(gfxCo
                                    const nsRect&       aDirty,
                                    uint32_t            aImageFlags,
                                    ExtendMode          aExtendMode,
                                    float               aOpacity)
 {
   PROFILER_LABEL("layout", "nsLayoutUtils::DrawBackgroundImage",
                  js::ProfileEntry::Category::GRAPHICS);
 
-  const Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(aImageSize))));
+  const Maybe<SVGImageContext>
+    svgContext(Some(SVGImageContext(Some(aImageSize), Nothing(), aOpacity)));
 
   /* Fast path when there is no need for image spacing */
   if (aRepeatSize.width == aDest.width && aRepeatSize.height == aDest.height) {
     return DrawImageInternal(aContext, aPresContext, aImage,
                              aSamplingFilter, aDest, aFill, aAnchor,
-                             aDirty, svgContext, aImageFlags, aExtendMode,
-                             aOpacity);
+                             aDirty, svgContext, aImageFlags, aExtendMode);
   }
 
   nsPoint firstTilePos = aDest.TopLeft() +
                          nsPoint(NSToIntFloor(float(aFill.x - aDest.x) / aRepeatSize.width) * aRepeatSize.width,
                                  NSToIntFloor(float(aFill.y - aDest.y) / aRepeatSize.height) * aRepeatSize.height);
   for (int32_t i = firstTilePos.x; i < aFill.XMost(); i += aRepeatSize.width) {
     for (int32_t j = firstTilePos.y; j < aFill.YMost(); j += aRepeatSize.height) {
       nsRect dest(i, j, aDest.width, aDest.height);
-      DrawResult result = DrawImageInternal(aContext, aPresContext, aImage, aSamplingFilter,
-                                            dest, dest, aAnchor, aDirty, svgContext,
-                                            aImageFlags, ExtendMode::CLAMP,
-                                            aOpacity);
+      DrawResult result = DrawImageInternal(aContext, aPresContext, aImage,
+                                            aSamplingFilter, dest, dest,
+                                            aAnchor, aDirty, svgContext,
+                                            aImageFlags, ExtendMode::CLAMP);
       if (result != DrawResult::SUCCESS) {
         return result;
       }
     }
   }
 
   return DrawResult::SUCCESS;
 }