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
--- 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();