Bug 1291280 - Part 2. Declare nsStyleImageLayers::Layer::mSourceURI as FragmentOrURI
MozReview-Commit-ID: 6KFb7MjlLqj
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2140,22 +2140,20 @@ nsComputedDOMStyle::DoGetImageLayerImage
// Since this layer does not refer to any source, Layer::mSourceURI must
// be nullptr too.
// 2. This layer refers to a local resource, e.g. mask-image:url(#mymask).
// For local references, there is no need to download any external
// resource, so Layer::mImage is not used.
// Instead, we store the local URI in one place -- on Layer::mSourceURI.
// Hence, we must serialize using mSourceURI (instead of
// SetValueToStyleImage()/mImage) in this case.
- bool isLocalURI = image.GetType() == eStyleImageType_Null &&
- aLayers.mLayers[i].mSourceURI;
- if (isLocalURI) {
+ if (aLayers.mLayers[i].mSourceURI.IsLocalRef()) {
// This is how we represent a 'mask-image' reference for a local URI,
// such as 'mask-image:url(#mymask)' or 'mask:url(#mymask)'
- val->SetURI(aLayers.mLayers[i].mSourceURI);
+ val->SetURI(aLayers.mLayers[i].mSourceURI.GetSourceURL());
} else {
SetValueToStyleImage(image, val);
}
valueList->AppendCSSValue(val.forget());
}
return valueList.forget();
@@ -6142,18 +6140,18 @@ nsComputedDOMStyle::DoGetMask()
!firstLayer.mSize.IsInitialValue() ||
!(firstLayer.mImage.GetType() == eStyleImageType_Null ||
firstLayer.mImage.GetType() == eStyleImageType_Image)) {
return nullptr;
}
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
- if (firstLayer.mSourceURI) {
- val->SetURI(firstLayer.mSourceURI);
+ if (firstLayer.mSourceURI.GetSourceURL()) {
+ val->SetURI(firstLayer.mSourceURI.GetSourceURL());
} else {
val->SetIdent(eCSSKeyword_none);
}
return val.forget();
}
#ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6652,28 +6652,28 @@ struct BackgroundItemComputer<nsCSSValue
RuleNodeCacheConditions& aConditions)
{
SetStyleImage(aStyleContext, aSpecifiedValue->mValue, aComputedValue,
aConditions);
}
};
template <>
-struct BackgroundItemComputer<nsCSSValueList, nsCOMPtr<nsIURI> >
+struct BackgroundItemComputer<nsCSSValueList, FragmentOrURL>
{
static void ComputeValue(nsStyleContext* aStyleContext,
const nsCSSValueList* aSpecifiedValue,
- nsCOMPtr<nsIURI>& aComputedValue,
+ FragmentOrURL& aComputedValue,
RuleNodeCacheConditions& aConditions)
{
if (eCSSUnit_Image == aSpecifiedValue->mValue.GetUnit() ||
eCSSUnit_URL == aSpecifiedValue->mValue.GetUnit()) {
- aComputedValue = aSpecifiedValue->mValue.GetURLValue();
+ aComputedValue.SetValue(&aSpecifiedValue->mValue);
} else if (eCSSUnit_Null != aSpecifiedValue->mValue.GetUnit()) {
- aComputedValue = nullptr;
+ aComputedValue.SetNull();
}
}
};
/* Helper function for ComputePositionValue.
* This function computes a single PositionCoord from two nsCSSValue objects,
* which represent an edge and an offset from that edge.
*/
@@ -10077,21 +10077,21 @@ nsRuleNode::ComputeSVGResetData(void* aS
FillBackgroundList(svgReset->mMask.mLayers,
&nsStyleImageLayers::Layer::mComposite,
svgReset->mMask.mCompositeCount, fillCount);
}
#else
// mask: none | <url>
const nsCSSValue* maskValue = aRuleData->ValueForMask();
if (eCSSUnit_URL == maskValue->GetUnit()) {
- svgReset->mMask.mLayers[0].mSourceURI = maskValue->GetURLValue();
+ svgReset->mMask.mLayers[0].mSourceURI.SetValue(maskValue);
} else if (eCSSUnit_None == maskValue->GetUnit() ||
eCSSUnit_Initial == maskValue->GetUnit() ||
eCSSUnit_Unset == maskValue->GetUnit()) {
- svgReset->mMask.mLayers[0].mSourceURI = nullptr;
+ svgReset->mMask.mLayers[0].mSourceURI.SetNull();
} else if (eCSSUnit_Inherit == maskValue->GetUnit()) {
conditions.SetUncacheable();
svgReset->mMask.mLayers[0].mSourceURI =
parentSVGReset->mMask.mLayers[0].mSourceURI;
}
#endif
svgReset->mMask.TrackImages(aContext->PresContext());
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2602,17 +2602,17 @@ 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].mImage.IsEmpty()) {
+ if (mLayers[i].mSourceURI.GetSourceURL() || !mLayers[i].mImage.IsEmpty()) {
return true;
}
}
return false;
}
bool
@@ -2829,44 +2829,51 @@ nsStyleImageLayers::Layer::operator==(co
mOrigin == aOther.mOrigin &&
mRepeat == aOther.mRepeat &&
mBlendMode == aOther.mBlendMode &&
mPosition == aOther.mPosition &&
mSize == aOther.mSize &&
mImage == aOther.mImage &&
mMaskMode == aOther.mMaskMode &&
mComposite == aOther.mComposite &&
- EqualURIs(mSourceURI, aOther.mSourceURI);
+ mSourceURI == aOther.mSourceURI;
}
nsChangeHint
nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewLayer,
nsChangeHint aPositionChangeHint) const
{
nsChangeHint hint = nsChangeHint(0);
- if (!EqualURIs(mSourceURI, aNewLayer.mSourceURI)) {
+ if (mSourceURI != aNewLayer.mSourceURI) {
hint |= nsChangeHint_RepaintFrame;
// If Layer::mSourceURI links to a SVG mask, it has a fragment. Not vice
// versa. Here are examples of URI contains a fragment, two of them link
// to a SVG mask:
// mask:url(a.svg#maskID); // The fragment of this URI is an ID of a mask
// // element in a.svg.
// mask:url(#localMaskID); // The fragment of this URI is an ID of a mask
// // element in local document.
// mask:url(b.svg#viewBoxID); // The fragment of this URI is an ID of a
// // viewbox defined in b.svg.
// That is, if mSourceURI has a fragment, it may link to a SVG mask; If
// not, it "must" not link to a SVG mask.
bool maybeSVGMask = false;
- if (mSourceURI) {
- mSourceURI->GetHasRef(&maybeSVGMask);
+ if (mSourceURI.IsLocalRef()) {
+ maybeSVGMask = true;
+ } else if (mSourceURI.GetSourceURL()) {
+ mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask);
}
- if (!maybeSVGMask && aNewLayer.mSourceURI) {
- aNewLayer.mSourceURI->GetHasRef(&maybeSVGMask);
+
+ if (!maybeSVGMask) {
+ if (aNewLayer.mSourceURI.IsLocalRef()) {
+ maybeSVGMask = true;
+ } else if (aNewLayer.mSourceURI.GetSourceURL()) {
+ aNewLayer.mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask);
+ }
}
// Return nsChangeHint_UpdateEffects and nsChangeHint_UpdateOverflow if
// either URI might link to an SVG mask.
if (maybeSVGMask) {
hint |= nsChangeHint_UpdateEffects;
// Mask changes require that we update the PreEffectsBBoxProperty,
// which is done during overflow computation.
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -680,17 +680,17 @@ struct nsStyleImageLayers {
return !(*this == aOther);
}
};
struct Layer;
friend struct Layer;
struct Layer {
nsStyleImage mImage; // [reset]
- nsCOMPtr<nsIURI> mSourceURI; // [reset]
+ FragmentOrURL mSourceURI; // [reset]
// mask-only property
// This property is used for mask layer only.
// For a background layer, it should always
// be the initial value, which is nullptr.
// Store mask-image URI so that we can resolve
// SVG mask path later.
Position mPosition; // [reset] See nsStyleConsts.h
Size mSize; // [reset]
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -390,19 +390,19 @@ nsSVGMarkerProperty::DoUpdate()
NS_IMPL_ISUPPORTS(nsSVGMaskProperty, nsISupports)
nsSVGMaskProperty::nsSVGMaskProperty(nsIFrame* aFrame)
{
const nsStyleSVGReset *svgReset = aFrame->StyleSVGReset();
for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) {
- nsSVGPaintingProperty* prop =
- new nsSVGPaintingProperty(svgReset->mMask.mLayers[i].mSourceURI, aFrame,
- false);
+ nsCOMPtr<nsIURI> maskUri = nsSVGEffects::GetMaskURI(aFrame, i);
+ nsSVGPaintingProperty* prop = new nsSVGPaintingProperty(maskUri, aFrame,
+ false);
mProperties.AppendElement(prop);
}
}
bool
nsSVGTextPathProperty::TargetIsValid()
{
Element* target = GetTarget();
@@ -959,8 +959,18 @@ nsSVGEffects::GetPaintURI(nsIFrame* aFra
nsStyleSVGPaint nsStyleSVG::* aPaint)
{
const nsStyleSVG* svgStyle = aFrame->StyleSVG();
MOZ_ASSERT((svgStyle->*aPaint).mType ==
nsStyleSVGPaintType::eStyleSVGPaintType_Server);
return ResolveFragmentOrURL(aFrame, (svgStyle->*aPaint).mPaint.mPaintServer);
}
+
+already_AddRefed<nsIURI>
+nsSVGEffects::GetMaskURI(nsIFrame* aFrame, uint32_t aIndex)
+{
+ const nsStyleSVGReset* svgReset = aFrame->StyleSVGReset();
+ MOZ_ASSERT(svgReset->mMask.mLayers.Length() > aIndex);
+
+ return ResolveFragmentOrURL(aFrame,
+ &svgReset->mMask.mLayers[aIndex].mSourceURI);
+}
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -619,11 +619,17 @@ public:
static already_AddRefed<nsIURI>
GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter);
/**
* A helper function to resolve paint-server URL.
*/
static already_AddRefed<nsIURI>
GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint);
+
+ /**
+ * A helper function to resolve SVG mask URL.
+ */
+ static already_AddRefed<nsIURI>
+ GetMaskURI(nsIFrame* aFrame, uint32_t aIndex);
};
#endif /*NSSVGEFFECTS_H_*/