Bug 652991 - Part 5. Using FragmentOrURL to represent SVG clippath.
MozReview-Commit-ID: BErpWUQ5iQ1
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -3950,20 +3950,23 @@ StyleAnimationValue::ExtractComputedValu
case eCSSProperty_clip_path: {
const nsStyleSVGReset* svgReset =
static_cast<const nsStyleSVGReset*>(styleStruct);
const nsStyleClipPath& clipPath = svgReset->mClipPath;
const StyleClipPathType type = clipPath.GetType();
if (type == StyleClipPathType::URL) {
nsIDocument* doc = aStyleContext->PresContext()->Document();
+ nsString pathString;
+ clipPath.GetURL()->GetSourceString(pathString);
RefPtr<nsStringBuffer> uriAsStringBuffer =
- GetURIAsUtf16StringBuffer(clipPath.GetURL());
+ nsCSSValue::BufferFromString(pathString);
+
RefPtr<mozilla::css::URLValue> url =
- new mozilla::css::URLValue(clipPath.GetURL(),
+ new mozilla::css::URLValue(clipPath.GetURL()->GetSourceURL(),
uriAsStringBuffer,
doc->GetDocumentURI(),
doc->NodePrincipal());
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(url);
aComputedValue.SetAndAdoptCSSValueValue(result.release(), eUnit_URL);
} else if (type == StyleClipPathType::Box) {
aComputedValue.SetIntValue(clipPath.GetSizingBox(),
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -6027,18 +6027,20 @@ nsComputedDOMStyle::DoGetClipPath()
switch (svg->mClipPath.GetType()) {
case StyleClipPathType::Shape:
return CreatePrimitiveValueForClipPath(svg->mClipPath.GetBasicShape(),
svg->mClipPath.GetSizingBox());
case StyleClipPathType::Box:
return CreatePrimitiveValueForClipPath(nullptr,
svg->mClipPath.GetSizingBox());
case StyleClipPathType::URL: {
+ // Bug 1288812 - we should only serialize fragment for local-ref URL.
+ nsCOMPtr<nsIURI> pathURI = svg->mClipPath.GetURL()->GetSourceURL();
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
- val->SetURI(svg->mClipPath.GetURL());
+ val->SetURI(pathURI);
return val.forget();
}
case StyleClipPathType::None_: {
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(eCSSKeyword_none);
return val.forget();
}
default:
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9880,20 +9880,17 @@ nsRuleNode::ComputeSVGResetData(void* aS
svgReset->mClipPath = nsStyleClipPath();
break;
case eCSSUnit_Inherit:
conditions.SetUncacheable();
svgReset->mClipPath = parentSVGReset->mClipPath;
break;
case eCSSUnit_URL: {
svgReset->mClipPath = nsStyleClipPath();
- nsIURI* url = clipPathValue->GetURLValue();
- if (url) {
- svgReset->mClipPath.SetURL(url);
- }
+ svgReset->mClipPath.SetURL(clipPathValue);
break;
}
case eCSSUnit_Array: {
svgReset->mClipPath = nsStyleClipPath();
SetStyleClipPathToCSSValue(&svgReset->mClipPath, clipPathValue, aContext,
mPresContext, conditions);
break;
}
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1117,17 +1117,17 @@ nsStyleClipPath::nsStyleClipPath()
}
nsStyleClipPath::nsStyleClipPath(const nsStyleClipPath& aSource)
: mURL(nullptr)
, mType(StyleClipPathType::None_)
, mSizingBox(StyleClipShapeSizing::NoBox)
{
if (aSource.mType == StyleClipPathType::URL) {
- SetURL(aSource.mURL);
+ CopyURL(aSource);
} else if (aSource.mType == StyleClipPathType::Shape) {
SetBasicShape(aSource.mBasicShape, aSource.mSizingBox);
} else if (aSource.mType == StyleClipPathType::Box) {
SetSizingBox(aSource.mSizingBox);
}
}
nsStyleClipPath::~nsStyleClipPath()
@@ -1138,17 +1138,17 @@ nsStyleClipPath::~nsStyleClipPath()
nsStyleClipPath&
nsStyleClipPath::operator=(const nsStyleClipPath& aOther)
{
if (this == &aOther) {
return *this;
}
if (aOther.mType == StyleClipPathType::URL) {
- SetURL(aOther.mURL);
+ CopyURL(aOther);
} else if (aOther.mType == StyleClipPathType::Shape) {
SetBasicShape(aOther.mBasicShape, aOther.mSizingBox);
} else if (aOther.mType == StyleClipPathType::Box) {
SetSizingBox(aOther.mSizingBox);
} else {
ReleaseRef();
mSizingBox = StyleClipShapeSizing::NoBox;
mType = StyleClipPathType::None_;
@@ -1178,33 +1178,47 @@ nsStyleClipPath::operator==(const nsStyl
void
nsStyleClipPath::ReleaseRef()
{
if (mType == StyleClipPathType::Shape) {
NS_ASSERTION(mBasicShape, "expected pointer");
mBasicShape->Release();
} else if (mType == StyleClipPathType::URL) {
NS_ASSERTION(mURL, "expected pointer");
- mURL->Release();
+ delete mURL;
}
// mBasicShap, mURL, etc. are all pointers in a union of pointers. Nulling
// one of them nulls all of them:
mURL = nullptr;
}
void
-nsStyleClipPath::SetURL(nsIURI* aURL)
+nsStyleClipPath::CopyURL(const nsStyleClipPath& aOther)
{
- NS_ASSERTION(aURL, "expected pointer");
ReleaseRef();
- mURL = aURL;
- mURL->AddRef();
+
+ mURL = new FragmentOrURL(*aOther.mURL);
mType = StyleClipPathType::URL;
}
+bool
+nsStyleClipPath::SetURL(const nsCSSValue* aValue)
+{
+ if (!aValue->GetURLValue()) {
+ return false;
+ }
+
+ ReleaseRef();
+
+ mURL = new FragmentOrURL();
+ mURL->SetValue(aValue);
+ mType = StyleClipPathType::URL;
+ return true;
+}
+
void
nsStyleClipPath::SetBasicShape(nsStyleBasicShape* aBasicShape,
StyleClipShapeSizing aSizingBox)
{
NS_ASSERTION(aBasicShape, "expected pointer");
ReleaseRef();
mBasicShape = aBasicShape;
mBasicShape->AddRef();
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3522,41 +3522,43 @@ struct nsStyleClipPath
bool operator!=(const nsStyleClipPath& aOther) const {
return !(*this == aOther);
}
mozilla::StyleClipPathType GetType() const {
return mType;
}
- nsIURI* GetURL() const {
+ FragmentOrURL* GetURL() const {
NS_ASSERTION(mType == mozilla::StyleClipPathType::URL, "wrong clip-path type");
return mURL;
}
- void SetURL(nsIURI* aURL);
+ bool SetURL(const nsCSSValue* aValue);
nsStyleBasicShape* GetBasicShape() const {
NS_ASSERTION(mType == mozilla::StyleClipPathType::Shape, "wrong clip-path type");
return mBasicShape;
}
void SetBasicShape(nsStyleBasicShape* mBasicShape,
mozilla::StyleClipShapeSizing aSizingBox =
mozilla::StyleClipShapeSizing::NoBox);
mozilla::StyleClipShapeSizing GetSizingBox() const { return mSizingBox; }
void SetSizingBox(mozilla::StyleClipShapeSizing aSizingBox);
private:
void ReleaseRef();
+ void CopyURL(const nsStyleClipPath& aOther);
+
void* operator new(size_t) = delete;
union {
nsStyleBasicShape* mBasicShape;
- nsIURI* mURL;
+ FragmentOrURL* mURL;
};
mozilla::StyleClipPathType mType;
mozilla::StyleClipShapeSizing mSizingBox;
};
struct nsStyleFilter
{
nsStyleFilter();
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -568,18 +568,19 @@ nsSVGEffects::GetEffectProperties(nsIFra
NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
EffectProperties result;
const nsStyleSVGReset *style = aFrame->StyleSVGReset();
result.mFilter = GetOrCreateFilterProperty(aFrame);
if (style->mClipPath.GetType() == StyleClipPathType::URL) {
+ nsCOMPtr<nsIURI> pathURI = nsSVGEffects::GetClipPathURI(aFrame);
result.mClipPath =
- GetPaintingProperty(style->mClipPath.GetURL(), aFrame, ClipPathProperty());
+ GetPaintingProperty(pathURI, aFrame, ClipPathProperty());
} else {
result.mClipPath = nullptr;
}
MOZ_ASSERT(style->mMask.mImageCount > 0);
result.mMask = style->mMask.HasLayerWithImage()
? GetOrCreateMaskProperty(aFrame) : nullptr;
@@ -905,8 +906,18 @@ ResolveFragmentOrURL(nsIFrame* aFrame, c
}
already_AddRefed<nsIURI>
nsSVGEffects::GetMarkerURI(nsIFrame* aFrame,
FragmentOrURL nsStyleSVG::* aMarker)
{
return ResolveFragmentOrURL(aFrame, &(aFrame->StyleSVG()->*aMarker));
}
+
+already_AddRefed<nsIURI>
+nsSVGEffects::GetClipPathURI(nsIFrame *aFrame)
+{
+ const nsStyleSVGReset* svgResetStyle = aFrame->StyleSVGReset();
+ MOZ_ASSERT(svgResetStyle->mClipPath.GetType() == NS_STYLE_CLIP_PATH_URL);
+
+ FragmentOrURL* url = svgResetStyle->mClipPath.GetURL();
+ return ResolveFragmentOrURL(aFrame, url);
+}
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -593,11 +593,17 @@ public:
GetPaintingPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
URIObserverHashtablePropertyDescriptor aProp);
/**
* A helper function to resolve marker's URL.
*/
static already_AddRefed<nsIURI>
GetMarkerURI(nsIFrame* aFrame, FragmentOrURL nsStyleSVG::* aMarker);
+
+ /**
+ * A helper function to resolve clip-path URL.
+ */
+ static already_AddRefed<nsIURI>
+ GetClipPathURI(nsIFrame* aFrame);
};
#endif /*NSSVGEFFECTS_H_*/