Bug 1343139 - Part 1. Implement nsStyleSVGReset::HasMask. draft
authorcku <cku@mozilla.com>
Tue, 07 Mar 2017 13:43:21 +0800
changeset 494515 c531aa4381bea57da54314f69cbc11016689f98a
parent 494263 b7e42143bbbc9dc3e5c05bd1e93b6485ce1d0ad4
child 494516 accfcc3190ea7e6e846807b34b1f53e1502740f6
child 494518 0423c2f31fdf55f4f5753526b921545ae9edd3c1
child 494520 bc649892d40aaf86dfa481f6c8a61b02c4500b0c
push id48047
push userbmo:cku@mozilla.com
push dateTue, 07 Mar 2017 08:05:15 +0000
bugs1343139
milestone55.0a1
Bug 1343139 - Part 1. Implement nsStyleSVGReset::HasMask. Implement this unil function to improve readability MozReview-Commit-ID: FLKOGyq180W
layout/painting/nsDisplayList.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGIntegrationUtils.cpp
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7864,18 +7864,17 @@ bool nsDisplayMask::TryMerge(nsDisplayIt
     return false;
   }
   if (aItem->GetClipChain() != GetClipChain()) {
     return false;
   }
 
   // Do not merge if mFrame has mask. Continuation frames should apply mask
   // independently(just like nsDisplayBackgroundImage).
-  const nsStyleSVGReset *style = mFrame->StyleSVGReset();
-  if (style->mMask.HasLayerWithImage()) {
+  if (mFrame->StyleSVGReset()->HasMask()) {
     return false;
   }
 
   nsDisplayMask* other = static_cast<nsDisplayMask*>(aItem);
   MergeFromTrackingMergedFrames(other);
   mEffectsBounds.UnionRect(mEffectsBounds,
     other->mEffectsBounds + other->mFrame->GetOffsetTo(mFrame));
 
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1207,16 +1207,35 @@ nsStyleSVGReset::CalcDifference(const ns
   }
 
   hint |= mMask.CalcDifference(aNewData.mMask,
                                nsStyleImageLayers::LayerType::Mask);
 
   return hint;
 }
 
+bool
+nsStyleSVGReset::HasMask() const
+{
+  for (uint32_t i = 0; i < mMask.mImageCount; i++) {
+    // mMask.mLayers[i].mSourceURI can be nullptr if mask-image prop value is
+    // <element-reference> or <gradient>.
+    // mMask.mLayers[i].mImage can be empty if mask-image prop value is a
+    // reference to SVG mask element.
+    //
+    // So we need to test both mSourceURI and mImage.
+    if ((mMask.mLayers[i].mSourceURI && mMask.mLayers[i].mSourceURI->GetURI()) ||
+        !mMask.mLayers[i].mImage.IsEmpty()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 // nsStyleSVGPaint implementation
 nsStyleSVGPaint::nsStyleSVGPaint(nsStyleSVGPaintType aType)
   : mType(aType)
   , mFallbackColor(NS_RGB(0, 0, 0))
 {
   MOZ_ASSERT(aType == nsStyleSVGPaintType(0) ||
              aType == eStyleSVGPaintType_None ||
              aType == eStyleSVGPaintType_Color);
@@ -2580,34 +2599,16 @@ nsStyleImageLayers::CalcDifference(const
       mPositionYCount != aNewLayers.mPositionYCount ||
       mSizeCount != aNewLayers.mSizeCount) {
     hint |= nsChangeHint_NeutralChange;
   }
 
   return hint;
 }
 
-bool
-nsStyleImageLayers::HasLayerWithImage() const
-{
-  for (uint32_t i = 0; i < mImageCount; i++) {
-    // mLayers[i].mSourceURI can be nullptr if mask-image prop value is
-    // <element-reference> or <gradient>
-    // mLayers[i].mImage can be empty if mask-image prop value is a reference
-    // to SVG mask element.
-    // So we need to test both mSourceURI and mImage.
-    if ((mLayers[i].mSourceURI && mLayers[i].mSourceURI->GetURI()) ||
-        !mLayers[i].mImage.IsEmpty()) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
 nsStyleImageLayers&
 nsStyleImageLayers::operator=(const nsStyleImageLayers& aOther)
 {
   mAttachmentCount = aOther.mAttachmentCount;
   mClipCount = aOther.mClipCount;
   mOriginCount = aOther.mOriginCount;
   mRepeatCount = aOther.mRepeatCount;
   mPositionXCount = aOther.mPositionXCount;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -899,17 +899,16 @@ struct nsStyleImageLayers {
     for (uint32_t i = 0; i < mImageCount; ++i) {
       mLayers[i].ResolveImage(aContext);
     }
   }
 
   nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
                               nsStyleImageLayers::LayerType aType) const;
 
-  bool HasLayerWithImage() const;
   nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
   nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther);
   bool operator==(const nsStyleImageLayers& aOther) const;
 
   static const nsCSSPropertyID kBackgroundLayerTable[];
   static const nsCSSPropertyID kMaskLayerTable[];
 
   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
@@ -3877,16 +3876,18 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
            nsChangeHint_ReflowChangesSizeOrPosition |
            nsChangeHint_ClearAncestorIntrinsics;
   }
 
   bool HasClipPath() const {
     return mClipPath.GetType() != mozilla::StyleShapeSourceType::None;
   }
 
+  bool HasMask() const;
+
   bool HasNonScalingStroke() const {
     return mVectorEffect == NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE;
   }
 
   nsStyleImageLayers    mMask;
   mozilla::StyleShapeSource mClipPath;// [reset]
   nscolor          mStopColor;        // [reset]
   nscolor          mFloodColor;       // [reset]
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -583,17 +583,17 @@ nsSVGEffects::GetEffectProperties(nsIFra
     nsCOMPtr<nsIURI> pathURI = nsSVGEffects::GetClipPathURI(aFrame);
     result.mClipPath =
       GetPaintingProperty(pathURI, aFrame, ClipPathProperty());
   } else {
     result.mClipPath = nullptr;
   }
 
   MOZ_ASSERT(style->mMask.mImageCount > 0);
-  result.mMask = style->mMask.HasLayerWithImage()
+  result.mMask = style->HasMask()
                  ? GetOrCreateMaskProperty(aFrame) : nullptr;
 
   return result;
 }
 
 nsSVGPaintServerFrame *
 nsSVGEffects::GetPaintServer(nsIFrame* aTargetFrame,
                              nsStyleSVGPaint nsStyleSVG::* aPaint,
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -132,26 +132,24 @@ bool
 nsSVGIntegrationUtils::UsingEffectsForFrame(const nsIFrame* aFrame)
 {
   // Even when SVG display lists are disabled, returning true for SVG frames
   // does not adversely affect any of our callers. Therefore we don't bother
   // checking the SDL prefs here, since we don't know if we're being called for
   // painting or hit-testing anyway.
   const nsStyleSVGReset *style = aFrame->StyleSVGReset();
   return aFrame->StyleEffects()->HasFilters() ||
-         style->HasClipPath() ||
-         style->mMask.HasLayerWithImage();
+         style->HasClipPath() || style->HasMask();
 }
 
 bool
 nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(const nsIFrame* aFrame)
 {
   const nsStyleSVGReset *style = aFrame->StyleSVGReset();
-  return style->HasClipPath() ||
-         style->mMask.HasLayerWithImage();
+  return style->HasClipPath() || style->HasMask();
 }
 
 nsPoint
 nsSVGIntegrationUtils::GetOffsetToBoundingBox(nsIFrame* aFrame)
 {
   if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     // Do NOT call GetAllInFlowRectsUnion for SVG - it will get the
     // covered region relative to the nsSVGOuterSVGFrame, which is absolutely