Bug 1288626 Part 6 - Generalize StyleClipPath to be template struct StyleShapeSource. r=heycam draft
authorTing-Yu Lin <tlin@mozilla.com>
Thu, 04 Aug 2016 13:43:08 +0800
changeset 398405 002a9f579d5f24ae167ed85dd1815e2358bfcdb7
parent 398404 3be2e33ba423e175f4e784ef4f716477ccbc2403
child 398406 ba601b9cd00747780b8fa1e14044c98608ababcf
push id25517
push userbmo:tlin@mozilla.com
push dateTue, 09 Aug 2016 03:27:51 +0000
reviewersheycam
bugs1288626
milestone51.0a1
Bug 1288626 Part 6 - Generalize StyleClipPath to be template struct StyleShapeSource. r=heycam The only difference between clip-path and shape-outside is the reference box enum, so I generalize StyleClipPath to be a template struct StyleShapeSource to accommodate both. I'll have to move all the method definition to the header to make the linker happy. The only logic change is calling operator==() instead of EqualURIs to compare urls in StyleShapeSource::operator==(). MozReview-Commit-ID: LOBGVVpnnB
layout/style/StyleAnimationValue.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/svg/nsCSSClipPathInstance.cpp
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -3573,17 +3573,17 @@ StyleClipBasicShapeToCSSArray(const Styl
       functionArray->Item(functionArray->Count() - 1).
                        SetArrayValue(radiusArray, eCSSUnit_Array);
       break;
     }
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown shape type");
       return false;
   }
-  aResult->Item(1).SetIntValue(aClipPath.GetSizingBox(),
+  aResult->Item(1).SetIntValue(aClipPath.GetReferenceBox(),
                                eCSSUnit_Enumerated);
   return true;
 }
 
 bool
 StyleAnimationValue::ExtractComputedValue(nsCSSProperty aProperty,
                                           nsStyleContext* aStyleContext,
                                           StyleAnimationValue& aComputedValue)
@@ -3960,17 +3960,17 @@ StyleAnimationValue::ExtractComputedValu
             nsIDocument* doc = aStyleContext->PresContext()->Document();
             RefPtr<mozilla::css::URLValue> url =
               FragmentOrURLToURLValue(clipPath.GetURL(), doc);
 
             auto result = MakeUnique<nsCSSValue>();
             result->SetURLValue(url);
             aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
           } else if (type == StyleShapeSourceType::Box) {
-            aComputedValue.SetIntValue(clipPath.GetSizingBox(),
+            aComputedValue.SetIntValue(clipPath.GetReferenceBox(),
                                        eUnit_Enumerated);
           } else if (type == StyleShapeSourceType::Shape) {
             RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
             if (!StyleClipBasicShapeToCSSArray(clipPath, result)) {
               return false;
             }
             aComputedValue.SetCSSValueArrayValue(result, eUnit_Shape);
 
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -6023,20 +6023,20 @@ nsComputedDOMStyle::CreatePrimitiveValue
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetClipPath()
 {
   const nsStyleSVGReset* svg = StyleSVGReset();
   switch (svg->mClipPath.GetType()) {
     case StyleShapeSourceType::Shape:
       return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(),
-                                             svg->mClipPath.GetSizingBox());
+                                             svg->mClipPath.GetReferenceBox());
     case StyleShapeSourceType::Box:
       return CreatePrimitiveValueForClipPath(nullptr,
-                                             svg->mClipPath.GetSizingBox());
+                                             svg->mClipPath.GetReferenceBox());
     case StyleShapeSourceType::URL: {
       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
       SetValueToFragmentOrURL(svg->mClipPath.GetURL(), val);
       return val.forget();
     }
     case StyleShapeSourceType::None_: {
       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
       val->SetIdent(eCSSKeyword_none);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9762,17 +9762,17 @@ SetStyleClipPathToCSSValue(StyleClipPath
       NS_NOTREACHED("unexpected value");
       return;
     }
   }
 
   if (basicShape) {
     aStyleClipPath->SetBasicShape(basicShape, sizingBox);
   } else {
-    aStyleClipPath->SetSizingBox(sizingBox);
+    aStyleClipPath->SetReferenceBox(sizingBox);
   }
 }
 
 // Returns true if the nsStyleFilter was successfully set using the nsCSSValue.
 static bool
 SetStyleFilterToCSSValue(nsStyleFilter* aStyleFilter,
                          const nsCSSValue& aValue,
                          nsStyleContext* aStyleContext,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1101,144 +1101,16 @@ StyleBasicShape::GetShapeTypeName() cons
     case StyleBasicShapeType::Inset:
       return eCSSKeyword_inset;
   }
   NS_NOTREACHED("unexpected type");
   return eCSSKeyword_UNKNOWN;
 }
 
 // --------------------
-// StyleClipPath
-//
-StyleClipPath::StyleClipPath()
-  : mURL(nullptr)
-  , mType(StyleShapeSourceType::None_)
-  , mSizingBox(StyleClipShapeSizing::NoBox)
-{
-}
-
-StyleClipPath::StyleClipPath(const StyleClipPath& aSource)
-  : mURL(nullptr)
-  , mType(StyleShapeSourceType::None_)
-  , mSizingBox(StyleClipShapeSizing::NoBox)
-{
-  if (aSource.mType == StyleShapeSourceType::URL) {
-    CopyURL(aSource);
-  } else if (aSource.mType == StyleShapeSourceType::Shape) {
-    SetBasicShape(aSource.mBasicShape, aSource.mSizingBox);
-  } else if (aSource.mType == StyleShapeSourceType::Box) {
-    SetSizingBox(aSource.mSizingBox);
-  }
-}
-
-StyleClipPath::~StyleClipPath()
-{
-  ReleaseRef();
-}
-
-StyleClipPath&
-StyleClipPath::operator=(const StyleClipPath& aOther)
-{
-  if (this == &aOther) {
-    return *this;
-  }
-
-  if (aOther.mType == StyleShapeSourceType::URL) {
-    CopyURL(aOther);
-  } else if (aOther.mType == StyleShapeSourceType::Shape) {
-    SetBasicShape(aOther.mBasicShape, aOther.mSizingBox);
-  } else if (aOther.mType == StyleShapeSourceType::Box) {
-    SetSizingBox(aOther.mSizingBox);
-  } else {
-    ReleaseRef();
-    mSizingBox = StyleClipShapeSizing::NoBox;
-    mType = StyleShapeSourceType::None_;
-  }
-  return *this;
-}
-
-bool
-StyleClipPath::operator==(const StyleClipPath& aOther) const
-{
-  if (mType != aOther.mType) {
-    return false;
-  }
-
-  if (mType == StyleShapeSourceType::URL) {
-    return EqualURIs(mURL, aOther.mURL);
-  } else if (mType == StyleShapeSourceType::Shape) {
-    return *mBasicShape == *aOther.mBasicShape &&
-           mSizingBox == aOther.mSizingBox;
-  } else if (mType == StyleShapeSourceType::Box) {
-    return mSizingBox == aOther.mSizingBox;
-  }
-
-  return true;
-}
-
-void
-StyleClipPath::ReleaseRef()
-{
-  if (mType == StyleShapeSourceType::Shape) {
-    NS_ASSERTION(mBasicShape, "expected pointer");
-    mBasicShape->Release();
-  } else if (mType == StyleShapeSourceType::URL) {
-    NS_ASSERTION(mURL, "expected pointer");
-    delete mURL;
-  }
-  // mBasicShap, mURL, etc. are all pointers in a union of pointers. Nulling
-  // one of them nulls all of them:
-  mURL = nullptr;
-}
-
-void
-StyleClipPath::CopyURL(const StyleClipPath& aOther)
-{
-  ReleaseRef();
-
-  mURL = new FragmentOrURL(*aOther.mURL);
-  mType = StyleShapeSourceType::URL;
-}
-
-bool
-StyleClipPath::SetURL(const nsCSSValue* aValue)
-{
-  if (!aValue->GetURLValue()) {
-    return false;
-  }
-
-  ReleaseRef();
-
-  mURL = new FragmentOrURL();
-  mURL->SetValue(aValue);
-  mType = StyleShapeSourceType::URL;
-  return true;
-}
-
-void
-StyleClipPath::SetBasicShape(StyleBasicShape* aBasicShape,
-                             StyleClipShapeSizing aSizingBox)
-{
-  NS_ASSERTION(aBasicShape, "expected pointer");
-  ReleaseRef();
-  mBasicShape = aBasicShape;
-  mBasicShape->AddRef();
-  mSizingBox = aSizingBox;
-  mType = StyleShapeSourceType::Shape;
-}
-
-void
-StyleClipPath::SetSizingBox(StyleClipShapeSizing aSizingBox)
-{
-  ReleaseRef();
-  mSizingBox = aSizingBox;
-  mType = StyleShapeSourceType::Box;
-}
-
-// --------------------
 // nsStyleFilter
 //
 nsStyleFilter::nsStyleFilter()
   : mType(NS_STYLE_FILTER_NONE)
   , mDropShadow(nullptr)
 {
   MOZ_COUNT_CTOR(nsStyleFilter);
 }
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3526,65 +3526,175 @@ private:
 
   // mCoordinates has coordinates for polygon or radii for
   // ellipse and circle.
   nsTArray<nsStyleCoord> mCoordinates;
   Position mPosition;
   nsStyleCorners mRadius;
 };
 
-struct StyleClipPath
+template<typename ReferenceBox>
+struct StyleShapeSource
 {
-  StyleClipPath();
-  StyleClipPath(const StyleClipPath& aSource);
-  ~StyleClipPath();
-
-  StyleClipPath& operator=(const StyleClipPath& aOther);
-
-  bool operator==(const StyleClipPath& aOther) const;
-  bool operator!=(const StyleClipPath& aOther) const {
+  StyleShapeSource()
+    : mURL(nullptr)
+  {}
+
+  StyleShapeSource(const StyleShapeSource& aSource)
+    : StyleShapeSource()
+  {
+    if (aSource.mType == StyleShapeSourceType::URL) {
+      CopyURL(aSource);
+    } else if (aSource.mType == StyleShapeSourceType::Shape) {
+      SetBasicShape(aSource.mBasicShape, aSource.mReferenceBox);
+    } else if (aSource.mType == StyleShapeSourceType::Box) {
+      SetReferenceBox(aSource.mReferenceBox);
+    }
+  }
+
+  ~StyleShapeSource()
+  {
+    ReleaseRef();
+  }
+
+  StyleShapeSource& operator=(const StyleShapeSource& aOther)
+  {
+    if (this == &aOther) {
+      return *this;
+    }
+
+    if (aOther.mType == StyleShapeSourceType::URL) {
+      CopyURL(aOther);
+    } else if (aOther.mType == StyleShapeSourceType::Shape) {
+      SetBasicShape(aOther.mBasicShape, aOther.mReferenceBox);
+    } else if (aOther.mType == StyleShapeSourceType::Box) {
+      SetReferenceBox(aOther.mReferenceBox);
+    } else {
+      ReleaseRef();
+      mReferenceBox = ReferenceBox::NoBox;
+      mType = StyleShapeSourceType::None_;
+    }
+    return *this;
+  }
+
+  bool operator==(const StyleShapeSource& aOther) const
+  {
+    if (mType != aOther.mType) {
+      return false;
+    }
+
+    if (mType == StyleShapeSourceType::URL) {
+      return mURL == aOther.mURL;
+    } else if (mType == StyleShapeSourceType::Shape) {
+      return *mBasicShape == *aOther.mBasicShape &&
+             mReferenceBox == aOther.mReferenceBox;
+    } else if (mType == StyleShapeSourceType::Box) {
+      return mReferenceBox == aOther.mReferenceBox;
+    }
+
+    return true;
+  }
+
+  bool operator!=(const StyleShapeSource& aOther) const
+  {
     return !(*this == aOther);
   }
 
-  StyleShapeSourceType GetType() const {
+  StyleShapeSourceType GetType() const
+  {
     return mType;
   }
 
-  FragmentOrURL* GetURL() const {
+  FragmentOrURL* GetURL() const
+  {
     MOZ_ASSERT(mType == StyleShapeSourceType::URL, "Wrong shape source type!");
     return mURL;
   }
-  bool SetURL(const nsCSSValue* aValue);
-
-  StyleBasicShape* GetBasicShape() const {
+
+  bool SetURL(const nsCSSValue* aValue)
+  {
+    if (!aValue->GetURLValue()) {
+      return false;
+    }
+
+    ReleaseRef();
+
+    mURL = new FragmentOrURL();
+    mURL->SetValue(aValue);
+    mType = StyleShapeSourceType::URL;
+    return true;
+  }
+
+  StyleBasicShape* GetBasicShape() const
+  {
     MOZ_ASSERT(mType == StyleShapeSourceType::Shape, "Wrong shape source type!");
     return mBasicShape;
   }
 
-  void SetBasicShape(StyleBasicShape* mBasicShape,
-                     StyleClipShapeSizing aSizingBox =
-                     StyleClipShapeSizing::NoBox);
-
-  StyleClipShapeSizing GetSizingBox() const { return mSizingBox; }
-  void SetSizingBox(StyleClipShapeSizing aSizingBox);
+  void SetBasicShape(StyleBasicShape* aBasicShape,
+                     ReferenceBox aReferenceBox)
+  {
+    NS_ASSERTION(aBasicShape, "expected pointer");
+    ReleaseRef();
+    mBasicShape = aBasicShape;
+    mBasicShape->AddRef();
+    mReferenceBox = aReferenceBox;
+    mType = StyleShapeSourceType::Shape;
+  }
+
+  ReferenceBox GetReferenceBox() const
+  {
+    MOZ_ASSERT(mType == StyleShapeSourceType::Box ||
+               mType == StyleShapeSourceType::Shape,
+               "Wrong shape source type!");
+    return mReferenceBox;
+  }
+
+  void SetReferenceBox(ReferenceBox aReferenceBox)
+  {
+    ReleaseRef();
+    mReferenceBox = aReferenceBox;
+    mType = StyleShapeSourceType::Box;
+  }
 
 private:
-  void ReleaseRef();
-  void CopyURL(const StyleClipPath& aOther);
+  void ReleaseRef()
+  {
+    if (mType == StyleShapeSourceType::Shape) {
+      NS_ASSERTION(mBasicShape, "expected pointer");
+      mBasicShape->Release();
+    } else if (mType == StyleShapeSourceType::URL) {
+      NS_ASSERTION(mURL, "expected pointer");
+      delete mURL;
+    }
+    // Both mBasicShape and mURL are pointers in a union. Nulling one of them
+    // nulls both of them.
+    mURL = nullptr;
+  }
+
+  void CopyURL(const StyleShapeSource& aOther)
+  {
+    ReleaseRef();
+
+    mURL = new FragmentOrURL(*aOther.mURL);
+    mType = StyleShapeSourceType::URL;
+  }
 
   void* operator new(size_t) = delete;
 
   union {
     StyleBasicShape* mBasicShape;
     FragmentOrURL* mURL;
   };
-  StyleShapeSourceType mType;
-  StyleClipShapeSizing mSizingBox;
+  StyleShapeSourceType mType = StyleShapeSourceType::None_;
+  ReferenceBox mReferenceBox = ReferenceBox::NoBox;
 };
 
+using StyleClipPath = StyleShapeSource<StyleClipShapeSizing>;
+
 } // namespace mozilla
 
 struct nsStyleFilter
 {
   nsStyleFilter();
   nsStyleFilter(const nsStyleFilter& aSource);
   ~nsStyleFilter();
 
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -62,17 +62,17 @@ nsCSSClipPathInstance::HitTestBasicShape
   return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
 }
 
 already_AddRefed<Path>
 nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
 {
   nsRect r;
   // XXXkrit SVG needs to use different boxes.
-  switch (mClipPathStyle.GetSizingBox()) {
+  switch (mClipPathStyle.GetReferenceBox()) {
     case StyleClipShapeSizing::Content:
       r = mTargetFrame->GetContentRectRelativeToSelf();
       break;
     case StyleClipShapeSizing::Padding:
       r = mTargetFrame->GetPaddingRectRelativeToSelf();
       break;
     case StyleClipShapeSizing::Margin:
       r = mTargetFrame->GetMarginRectRelativeToSelf();