diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index cd8ec8c41718..2d3f317c1f0b 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2267,7 +2267,7 @@ static already_AddRefed ResolveFilterStyleForServo( } bool CanvasRenderingContext2D::ParseFilter( - const nsAString& aString, nsTArray& aFilterChain, + const nsAString& aString, StyleOwnedSlice& aFilterChain, ErrorResult& aError) { if (!mCanvasElement && !mDocShell) { NS_WARNING( @@ -2302,14 +2302,14 @@ bool CanvasRenderingContext2D::ParseFilter( void CanvasRenderingContext2D::SetFilter(const nsAString& aFilter, ErrorResult& aError) { - nsTArray filterChain; + StyleOwnedSlice filterChain; if (ParseFilter(aFilter, filterChain, aError)) { CurrentState().filterString = aFilter; - filterChain.SwapElements(CurrentState().filterChain); + CurrentState().filterChain = std::move(filterChain); if (mCanvasElement) { CurrentState().autoSVGFiltersObserver = SVGObserverUtils::ObserveFiltersForCanvasContext( - this, mCanvasElement, CurrentState().filterChain); + this, mCanvasElement, CurrentState().filterChain.AsSpan()); UpdateFilter(); } } @@ -2376,7 +2376,8 @@ void CanvasRenderingContext2D::UpdateFilter() { (mCanvasElement && mCanvasElement->IsWriteOnly()); CurrentState().filter = nsFilterInstance::GetFilterDescription( - mCanvasElement, CurrentState().filterChain, sourceGraphicIsTainted, + mCanvasElement, CurrentState().filterChain.AsSpan(), + sourceGraphicIsTainted, CanvasUserSpaceMetrics( GetSize(), CurrentState().fontFont, CurrentState().fontLanguage, CurrentState().fontExplicitLanguage, presShell->GetPresContext()), diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index eca324e8fe3a..9743e57017e2 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -566,7 +566,8 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal, // Returns whether a filter was successfully parsed. bool ParseFilter(const nsAString& aString, - nsTArray& aFilterChain, ErrorResult& aError); + StyleOwnedSlice& aFilterChain, + ErrorResult& aError); // Returns whether the font was successfully updated. bool SetFontInternal(const nsAString& aFont, mozilla::ErrorResult& aError); @@ -966,7 +967,7 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal, mozilla::gfx::JoinStyle lineJoin = mozilla::gfx::JoinStyle::MITER_OR_BEVEL; nsString filterString = nsString(u"none"); - nsTArray filterChain; + StyleOwnedSlice filterChain; // RAII object that we obtain when we start to observer SVG filter elements // for rendering changes. When released we stop observing the SVG elements. nsCOMPtr autoSVGFiltersObserver; diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 9e03060d34fc..1386e2e6b64f 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -9981,69 +9981,63 @@ static float ClampStdDeviation(float aStdDeviation) { return std::min(std::max(0.0f, aStdDeviation), 100.0f); } -bool nsDisplayFilters::CreateWebRenderCSSFilters(WrFiltersHolder& wrFilters) { +bool nsDisplayFilters::CreateWebRenderCSSFilters(WrFiltersHolder& aWrFilters) { // All CSS filters are supported by WebRender. SVG filters are not fully // supported, those use NS_STYLE_FILTER_URL and are handled separately. - const nsTArray& filters = mFrame->StyleEffects()->mFilters; + Span filters = mFrame->StyleEffects()->mFilters.AsSpan(); // If there are too many filters to render, then just pretend that we // succeeded, and don't render any of them. if (filters.Length() > StaticPrefs::WebRenderMaxFilterOpsPerChain()) { return true; } - wrFilters.filters.SetCapacity(filters.Length()); - - for (const nsStyleFilter& filter : filters) { - switch (filter.GetType()) { - case NS_STYLE_FILTER_BRIGHTNESS: - wrFilters.filters.AppendElement(wr::FilterOp::Brightness( - filter.GetFilterParameter().GetFactorOrPercentValue())); + aWrFilters.filters.SetCapacity(filters.Length()); + auto& wrFilters = aWrFilters.filters; + for (const StyleFilter& filter : filters) { + switch (filter.tag) { + case StyleFilter::Tag::Brightness: + wrFilters.AppendElement( + wr::FilterOp::Brightness(filter.AsBrightness())); break; - case NS_STYLE_FILTER_CONTRAST: - wrFilters.filters.AppendElement(wr::FilterOp::Contrast( - filter.GetFilterParameter().GetFactorOrPercentValue())); + case StyleFilter::Tag::Contrast: + wrFilters.AppendElement(wr::FilterOp::Contrast(filter.AsContrast())); break; - case NS_STYLE_FILTER_GRAYSCALE: - wrFilters.filters.AppendElement(wr::FilterOp::Grayscale( - filter.GetFilterParameter().GetFactorOrPercentValue())); + case StyleFilter::Tag::Grayscale: + wrFilters.AppendElement(wr::FilterOp::Grayscale(filter.AsGrayscale())); break; - case NS_STYLE_FILTER_INVERT: - wrFilters.filters.AppendElement(wr::FilterOp::Invert( - filter.GetFilterParameter().GetFactorOrPercentValue())); + case StyleFilter::Tag::Invert: + wrFilters.AppendElement(wr::FilterOp::Invert(filter.AsInvert())); break; - case NS_STYLE_FILTER_OPACITY: { - float opacity = filter.GetFilterParameter().GetFactorOrPercentValue(); - wrFilters.filters.AppendElement(wr::FilterOp::Opacity( + case StyleFilter::Tag::Opacity: { + float opacity = filter.AsOpacity(); + wrFilters.AppendElement(wr::FilterOp::Opacity( wr::PropertyBinding::Value(opacity), opacity)); break; } - case NS_STYLE_FILTER_SATURATE: - wrFilters.filters.AppendElement(wr::FilterOp::Saturate( - filter.GetFilterParameter().GetFactorOrPercentValue())); + case StyleFilter::Tag::Saturate: + wrFilters.AppendElement(wr::FilterOp::Saturate(filter.AsSaturate())); break; - case NS_STYLE_FILTER_SEPIA: { - wrFilters.filters.AppendElement(wr::FilterOp::Sepia( - filter.GetFilterParameter().GetFactorOrPercentValue())); + case StyleFilter::Tag::Sepia: + wrFilters.AppendElement(wr::FilterOp::Sepia(filter.AsSepia())); + break; + case StyleFilter::Tag::HueRotate: { + wrFilters.AppendElement( + wr::FilterOp::HueRotate(filter.AsHueRotate().ToDegrees())); break; } - case NS_STYLE_FILTER_HUE_ROTATE: { - wrFilters.filters.AppendElement(wr::FilterOp::HueRotate( - (float)filter.GetFilterParameter().GetAngleValueInDegrees())); - break; - } - case NS_STYLE_FILTER_BLUR: { + case StyleFilter::Tag::Blur: { + // TODO(emilio): we should go directly from css pixels -> device pixels. float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - wrFilters.filters.AppendElement(mozilla::wr::FilterOp::Blur( + wrFilters.AppendElement(mozilla::wr::FilterOp::Blur( ClampStdDeviation(NSAppUnitsToFloatPixels( - filter.GetFilterParameter().GetCoordValue(), - appUnitsPerDevPixel)))); + filter.AsBlur().ToAppUnits(), appUnitsPerDevPixel)))); break; } - case NS_STYLE_FILTER_DROP_SHADOW: { + case StyleFilter::Tag::DropShadow: { float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel(); - const StyleSimpleShadow& shadow = filter.GetDropShadow(); + const StyleSimpleShadow& shadow = filter.AsDropShadow(); nscolor color = shadow.color.CalcColor(mFrame); wr::Shadow wrShadow; @@ -10056,9 +10050,7 @@ bool nsDisplayFilters::CreateWebRenderCSSFilters(WrFiltersHolder& wrFilters) { appUnitsPerDevPixel); wrShadow.color = {NS_GET_R(color) / 255.0f, NS_GET_G(color) / 255.0f, NS_GET_B(color) / 255.0f, NS_GET_A(color) / 255.0f}; - auto filterOp = wr::FilterOp::DropShadow(wrShadow); - - wrFilters.filters.AppendElement(filterOp); + wrFilters.AppendElement(wr::FilterOp::DropShadow(wrShadow)); break; } default: diff --git a/layout/style/GeckoBindings.cpp b/layout/style/GeckoBindings.cpp index 35a822f44fe1..3e850c6bfa82 100644 --- a/layout/style/GeckoBindings.cpp +++ b/layout/style/GeckoBindings.cpp @@ -1551,20 +1551,6 @@ void Gecko_SetToSVGPath(StyleShapeSource* aShape, aShape->SetPath(MakeUnique(aCommands, aFill)); } -void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len) { - effects->mFilters.Clear(); - effects->mFilters.SetLength(new_len); -} - -void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest) { - aDest->mFilters = aSrc->mFilters; -} - -void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects, - const StyleComputedUrl* aURL) { - aEffects->SetURL(*aURL); -} - void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest, const nsStyleSVGPaint* aSrc) { *aDest = *aSrc; diff --git a/layout/style/GeckoBindings.h b/layout/style/GeckoBindings.h index 3181dbb3e1d4..c181cc4c62c1 100644 --- a/layout/style/GeckoBindings.h +++ b/layout/style/GeckoBindings.h @@ -536,9 +536,6 @@ void Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len); void Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest); -void Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* effects, - const mozilla::StyleComputedUrl* url); - void Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* dest, const nsStyleSVGPaint* src); diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index b235363815f3..af72c3e5a3b3 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -507,6 +507,7 @@ cbindgen-types = [ { gecko = "StyleComputedUrl", servo = "gecko::url::ComputedUrl" }, { gecko = "StyleComputedImageUrl", servo = "gecko::url::ComputedImageUrl" }, { gecko = "StyleLoadData", servo = "gecko::url::LoadData" }, + { gecko = "StyleGenericFilter", servo = "values::generics::effects::Filter" }, ] mapped-generic-types = [ diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index ad5c5b0df5b6..baa9ea110d7f 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -23,7 +23,21 @@ namespace mozilla { template -inline StyleOwnedSlice::StyleOwnedSlice(const StyleOwnedSlice& aOther) { +inline void StyleOwnedSlice::Clear() { + if (!len) { + return; + } + for (size_t i : IntegerRange(len)) { + ptr[i].~T(); + } + free(ptr); + ptr = (T*)alignof(T); + len = 0; +} + +template +inline void StyleOwnedSlice::CopyFrom(const StyleOwnedSlice& aOther) { + Clear(); len = aOther.len; if (!len) { ptr = (T*)alignof(T); @@ -37,24 +51,36 @@ inline StyleOwnedSlice::StyleOwnedSlice(const StyleOwnedSlice& aOther) { } template -inline StyleOwnedSlice::StyleOwnedSlice(StyleOwnedSlice&& aOther) { - len = aOther.len; - ptr = aOther.ptr; - aOther.ptr = (T*)alignof(T); - aOther.len = 0; +inline void StyleOwnedSlice::SwapElements(StyleOwnedSlice& aOther) { + std::swap(ptr, aOther.ptr); + std::swap(len, aOther.len); } template -inline void StyleOwnedSlice::Clear() { - if (!len) { - return; - } - for (size_t i : IntegerRange(len)) { - ptr[i].~T(); - } - free(ptr); - ptr = (T*)alignof(T); - len = 0; +inline StyleOwnedSlice::StyleOwnedSlice(const StyleOwnedSlice& aOther) + : StyleOwnedSlice() { + CopyFrom(aOther); +} + +template +inline StyleOwnedSlice::StyleOwnedSlice(StyleOwnedSlice&& aOther) + : StyleOwnedSlice() { + SwapElements(aOther); +} + +template +inline StyleOwnedSlice& StyleOwnedSlice::operator=( + const StyleOwnedSlice& aOther) { + CopyFrom(aOther); + return *this; +} + +template +inline StyleOwnedSlice& StyleOwnedSlice::operator=( + StyleOwnedSlice&& aOther) { + Clear(); + SwapElements(aOther); + return *this; } template diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index f1fa7f588137..23dbe04f4c76 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -376,21 +376,6 @@ const KTableEntry nsCSSProps::kTextEmphasisStyleShapeKTable[] = { {eCSSKeyword_sesame, NS_STYLE_TEXT_EMPHASIS_STYLE_SESAME}, {eCSSKeyword_UNKNOWN, -1}}; -// keyword tables for SVG properties - -const KTableEntry nsCSSProps::kFilterFunctionKTable[] = { - {eCSSKeyword_blur, NS_STYLE_FILTER_BLUR}, - {eCSSKeyword_brightness, NS_STYLE_FILTER_BRIGHTNESS}, - {eCSSKeyword_contrast, NS_STYLE_FILTER_CONTRAST}, - {eCSSKeyword_grayscale, NS_STYLE_FILTER_GRAYSCALE}, - {eCSSKeyword_invert, NS_STYLE_FILTER_INVERT}, - {eCSSKeyword_opacity, NS_STYLE_FILTER_OPACITY}, - {eCSSKeyword_saturate, NS_STYLE_FILTER_SATURATE}, - {eCSSKeyword_sepia, NS_STYLE_FILTER_SEPIA}, - {eCSSKeyword_hue_rotate, NS_STYLE_FILTER_HUE_ROTATE}, - {eCSSKeyword_drop_shadow, NS_STYLE_FILTER_DROP_SHADOW}, - {eCSSKeyword_UNKNOWN, -1}}; - int32_t nsCSSProps::FindIndexOfKeyword(nsCSSKeyword aKeyword, const KTableEntry aTable[]) { if (eCSSKeyword_UNKNOWN == aKeyword) { diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 2410d90164d7..4eaa14920527 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -290,7 +290,6 @@ class nsCSSProps { // Not const because we modify its entries when the pref // "layout.css.background-clip.text" changes: static const KTableEntry kShapeRadiusKTable[]; - static const KTableEntry kFilterFunctionKTable[]; static const KTableEntry kBoxShadowTypeKTable[]; static const KTableEntry kCursorKTable[]; // Not const because we modify its entries when various diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index af777f21e80f..de3017ac4ba4 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -41,7 +41,6 @@ class nsDOMCSSValueList; struct nsMargin; class nsROCSSPrimitiveValue; class nsStyleCoord; -struct nsStyleFilter; class nsStyleGradient; struct nsStyleImage; class nsStyleSides; diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 3c70634556c6..f177447878b7 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -364,20 +364,6 @@ enum class StyleFlexDirection : uint8_t { // (rather than an internal numerical representation of some keyword). #define NS_STYLE_ORDER_INITIAL 0 -// See nsStyleFilter -#define NS_STYLE_FILTER_NONE 0 -#define NS_STYLE_FILTER_URL 1 -#define NS_STYLE_FILTER_BLUR 2 -#define NS_STYLE_FILTER_BRIGHTNESS 3 -#define NS_STYLE_FILTER_CONTRAST 4 -#define NS_STYLE_FILTER_GRAYSCALE 5 -#define NS_STYLE_FILTER_INVERT 6 -#define NS_STYLE_FILTER_OPACITY 7 -#define NS_STYLE_FILTER_SATURATE 8 -#define NS_STYLE_FILTER_SEPIA 9 -#define NS_STYLE_FILTER_HUE_ROTATE 10 -#define NS_STYLE_FILTER_DROP_SHADOW 11 - // See nsStyleFont #define NS_STYLE_FONT_SIZE_XXSMALL 0 #define NS_STYLE_FONT_SIZE_XSMALL 1 diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 48520645e030..eaed776e05be 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1010,93 +1010,6 @@ void StyleShapeSource::DoDestroy() { mType = StyleShapeSourceType::None; } -// -------------------- -// nsStyleFilter -// -nsStyleFilter::nsStyleFilter() : mType(NS_STYLE_FILTER_NONE) { - MOZ_COUNT_CTOR(nsStyleFilter); -} - -nsStyleFilter::nsStyleFilter(const nsStyleFilter& aSource) - : mType(NS_STYLE_FILTER_NONE) { - MOZ_COUNT_CTOR(nsStyleFilter); - if (aSource.mType == NS_STYLE_FILTER_URL) { - SetURL(aSource.mURL); - } else if (aSource.mType == NS_STYLE_FILTER_DROP_SHADOW) { - SetDropShadow(aSource.mDropShadow); - } else if (aSource.mType != NS_STYLE_FILTER_NONE) { - SetFilterParameter(aSource.mFilterParameter, aSource.mType); - } -} - -nsStyleFilter::~nsStyleFilter() { - ReleaseRef(); - MOZ_COUNT_DTOR(nsStyleFilter); -} - -nsStyleFilter& nsStyleFilter::operator=(const nsStyleFilter& aOther) { - if (this == &aOther) { - return *this; - } - - if (aOther.mType == NS_STYLE_FILTER_URL) { - SetURL(aOther.mURL); - } else if (aOther.mType == NS_STYLE_FILTER_DROP_SHADOW) { - SetDropShadow(aOther.mDropShadow); - } else if (aOther.mType != NS_STYLE_FILTER_NONE) { - SetFilterParameter(aOther.mFilterParameter, aOther.mType); - } else { - ReleaseRef(); - mType = NS_STYLE_FILTER_NONE; - } - - return *this; -} - -bool nsStyleFilter::operator==(const nsStyleFilter& aOther) const { - if (mType != aOther.mType) { - return false; - } - - if (mType == NS_STYLE_FILTER_URL) { - return mURL == aOther.mURL; - } else if (mType == NS_STYLE_FILTER_DROP_SHADOW) { - return mDropShadow == aOther.mDropShadow; - } else if (mType != NS_STYLE_FILTER_NONE) { - return mFilterParameter == aOther.mFilterParameter; - } - - return true; -} - -void nsStyleFilter::ReleaseRef() { - if (mType == NS_STYLE_FILTER_DROP_SHADOW) { - mDropShadow.~StyleSimpleShadow(); - } else if (mType == NS_STYLE_FILTER_URL) { - mURL.~StyleComputedUrl(); - } -} - -void nsStyleFilter::SetFilterParameter(const nsStyleCoord& aFilterParameter, - int32_t aType) { - ReleaseRef(); - mFilterParameter = aFilterParameter; - mType = aType; -} - -bool nsStyleFilter::SetURL(const StyleComputedUrl& aUrl) { - ReleaseRef(); - new (&mURL) StyleComputedUrl(aUrl); - mType = NS_STYLE_FILTER_URL; - return true; -} - -void nsStyleFilter::SetDropShadow(const StyleSimpleShadow& aSrc) { - ReleaseRef(); - new (&mDropShadow) StyleSimpleShadow(aSrc); - mType = NS_STYLE_FILTER_DROP_SHADOW; -} - // -------------------- // nsStyleSVGReset // diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 2e068954844e..0a68b53f7bdf 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -2546,60 +2546,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG { uint8_t mContextFlags; }; -struct nsStyleFilter { - nsStyleFilter(); - nsStyleFilter(const nsStyleFilter& aSource); - ~nsStyleFilter(); - void TriggerImageLoads(mozilla::dom::Document&, const nsStyleFilter*) {} - const static bool kHasTriggerImageLoads = false; - - nsStyleFilter& operator=(const nsStyleFilter& aOther); - - bool operator==(const nsStyleFilter& aOther) const; - bool operator!=(const nsStyleFilter& aOther) const { - return !(*this == aOther); - } - - uint32_t GetType() const { return mType; } - - const nsStyleCoord& GetFilterParameter() const { - NS_ASSERTION(mType != NS_STYLE_FILTER_DROP_SHADOW && - mType != NS_STYLE_FILTER_URL && - mType != NS_STYLE_FILTER_NONE, - "wrong filter type"); - return mFilterParameter; - } - void SetFilterParameter(const nsStyleCoord& aFilterParameter, int32_t aType); - - const mozilla::StyleComputedUrl& GetURL() const { - MOZ_ASSERT(mType == NS_STYLE_FILTER_URL, "wrong filter type"); - return mURL; - } - - bool SetURL(const mozilla::StyleComputedUrl& aUrl); - - const mozilla::StyleSimpleShadow& GetDropShadow() const { - NS_ASSERTION(mType == NS_STYLE_FILTER_DROP_SHADOW, "wrong filter type"); - return mDropShadow; - } - void SetDropShadow(const mozilla::StyleSimpleShadow&); - - private: - void ReleaseRef(); - - uint32_t mType; // NS_STYLE_FILTER_* - nsStyleCoord mFilterParameter; // coord, percent, factor, angle - union { - mozilla::StyleComputedUrl mURL; - mozilla::StyleSimpleShadow mDropShadow; - }; -}; - -template <> -struct nsTArray_CopyChooser { - typedef nsTArray_CopyWithConstructors Type; -}; - struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset { explicit nsStyleSVGReset(const mozilla::dom::Document&); nsStyleSVGReset(const nsStyleSVGReset& aSource); @@ -2666,7 +2612,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects { return false; } - nsTArray mFilters; + mozilla::StyleOwnedSlice mFilters; mozilla::StyleOwnedSlice mBoxShadow; nsRect mClip; // offsets from UL border edge float mOpacity; diff --git a/layout/svg/SVGObserverUtils.cpp b/layout/svg/SVGObserverUtils.cpp index eb532c1553af..83d2bbe448a2 100644 --- a/layout/svg/SVGObserverUtils.cpp +++ b/layout/svg/SVGObserverUtils.cpp @@ -628,7 +628,7 @@ nsSVGFilterFrame* SVGFilterObserver::GetAndObserveFilterFrame() { */ class SVGFilterObserverList : public nsISupports { public: - SVGFilterObserverList(const nsTArray& aFilters, + SVGFilterObserverList(Span aFilters, nsIContent* aFilteredElement, nsIFrame* aFilteredFrame = nullptr); @@ -684,25 +684,25 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGFilterObserverList) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -SVGFilterObserverList::SVGFilterObserverList( - const nsTArray& aFilters, nsIContent* aFilteredElement, - nsIFrame* aFilteredFrame) { - for (uint32_t i = 0; i < aFilters.Length(); i++) { - if (aFilters[i].GetType() != NS_STYLE_FILTER_URL) { +SVGFilterObserverList::SVGFilterObserverList(Span aFilters, + nsIContent* aFilteredElement, + nsIFrame* aFilteredFrame) { + for (const auto& filter : aFilters) { + if (!filter.IsUrl()) { continue; } + const auto& url = filter.AsUrl(); + // aFilteredFrame can be null if this filter belongs to a // CanvasRenderingContext2D. RefPtr filterURL; if (aFilteredFrame) { - filterURL = ResolveURLUsingLocalRef(aFilteredFrame, aFilters[i].GetURL()); + filterURL = ResolveURLUsingLocalRef(aFilteredFrame, url); } else { - nsCOMPtr resolvedURI = - aFilters[i].GetURL().ResolveLocalRef(aFilteredElement); + nsCOMPtr resolvedURI = url.ResolveLocalRef(aFilteredElement); if (resolvedURI) { - filterURL = new URLAndReferrerInfo(resolvedURI, - aFilters[i].GetURL().ExtraData()); + filterURL = new URLAndReferrerInfo(resolvedURI, url.ExtraData()); } } @@ -725,7 +725,7 @@ bool SVGFilterObserverList::ReferencesValidResources() { class SVGFilterObserverListForCSSProp final : public SVGFilterObserverList { public: - SVGFilterObserverListForCSSProp(const nsTArray& aFilters, + SVGFilterObserverListForCSSProp(Span aFilters, nsIFrame* aFilteredFrame) : SVGFilterObserverList(aFilters, aFilteredFrame->GetContent(), aFilteredFrame), @@ -769,7 +769,7 @@ class SVGFilterObserverListForCanvasContext final public: SVGFilterObserverListForCanvasContext(CanvasRenderingContext2D* aContext, Element* aCanvasElement, - nsTArray& aFilters) + Span aFilters) : SVGFilterObserverList(aFilters, aCanvasElement), mContext(aContext) {} void OnRenderingChange() override; @@ -1168,7 +1168,8 @@ static SVGFilterObserverListForCSSProp* GetOrCreateFilterObserverListForCSS( MOZ_ASSERT(observers, "this property should only store non-null values"); return observers; } - observers = new SVGFilterObserverListForCSSProp(effects->mFilters, aFrame); + observers = + new SVGFilterObserverListForCSSProp(effects->mFilters.AsSpan(), aFrame); NS_ADDREF(observers); aFrame->AddProperty(FilterProperty(), observers); return observers; @@ -1219,7 +1220,7 @@ SVGObserverUtils::ReferenceState SVGObserverUtils::GetFiltersIfObserving( already_AddRefed SVGObserverUtils::ObserveFiltersForCanvasContext( CanvasRenderingContext2D* aContext, Element* aCanvasElement, - nsTArray& aFilters) { + const Span aFilters) { return do_AddRef(new SVGFilterObserverListForCanvasContext( aContext, aCanvasElement, aFilters)); } @@ -1680,11 +1681,10 @@ already_AddRefed SVGObserverUtils::GetBaseURLForLocalRef( } already_AddRefed SVGObserverUtils::GetFilterURI( - nsIFrame* aFrame, const nsStyleFilter& aFilter) { - MOZ_ASSERT(aFrame->StyleEffects()->mFilters.Length()); - MOZ_ASSERT(aFilter.GetType() == NS_STYLE_FILTER_URL); - - return ResolveURLUsingLocalRef(aFrame, aFilter.GetURL()); + nsIFrame* aFrame, const StyleFilter& aFilter) { + MOZ_ASSERT(!aFrame->StyleEffects()->mFilters.IsEmpty()); + MOZ_ASSERT(aFilter.IsUrl()); + return ResolveURLUsingLocalRef(aFrame, aFilter.AsUrl()); } } // namespace mozilla diff --git a/layout/svg/SVGObserverUtils.h b/layout/svg/SVGObserverUtils.h index a8e05f84954b..1391a9a71e50 100644 --- a/layout/svg/SVGObserverUtils.h +++ b/layout/svg/SVGObserverUtils.h @@ -296,13 +296,13 @@ class SVGObserverUtils { * set is destroyed or has its filter style reset). * * XXXjwatt: It's a bit unfortunate that both we and - * CanvasRenderingContext2D::UpdateFilter process the list of nsStyleFilter + * CanvasRenderingContext2D::UpdateFilter process the list of StyleFilter * objects separately. It would be better to refactor things so that we only * do that work once. */ static already_AddRefed ObserveFiltersForCanvasContext( CanvasRenderingContext2D* aContext, Element* aCanvasElement, - nsTArray& aFilters); + Span aFilters); /** * Called when cycle collecting CanvasRenderingContext2D, and requires the @@ -403,7 +403,7 @@ class SVGObserverUtils { * A helper function to resolve filter URL. */ static already_AddRefed GetFilterURI( - nsIFrame* aFrame, const nsStyleFilter& aFilter); + nsIFrame* aFrame, const StyleFilter& aFilter); /** * Return a baseURL for resolving a local-ref URL. diff --git a/layout/svg/nsCSSFilterInstance.cpp b/layout/svg/nsCSSFilterInstance.cpp index 3260b4d9161a..7d7e56dc217e 100644 --- a/layout/svg/nsCSSFilterInstance.cpp +++ b/layout/svg/nsCSSFilterInstance.cpp @@ -30,7 +30,7 @@ static float ClampFactor(float aFactor) { } nsCSSFilterInstance::nsCSSFilterInstance( - const nsStyleFilter& aFilter, nscolor aShadowFallbackColor, + const StyleFilter& aFilter, nscolor aShadowFallbackColor, const nsIntRect& aTargetBoundsInFilterSpace, const gfxMatrix& aFrameSpaceInCSSPxToFilterSpaceTransform) : mFilter(aFilter), @@ -45,35 +45,35 @@ nsresult nsCSSFilterInstance::BuildPrimitives( FilterPrimitiveDescription descr = CreatePrimitiveDescription(aPrimitiveDescrs, aInputIsTainted); nsresult result; - switch (mFilter.GetType()) { - case NS_STYLE_FILTER_BLUR: + switch (mFilter.tag) { + case StyleFilter::Tag::Blur: result = SetAttributesForBlur(descr); break; - case NS_STYLE_FILTER_BRIGHTNESS: + case StyleFilter::Tag::Brightness: result = SetAttributesForBrightness(descr); break; - case NS_STYLE_FILTER_CONTRAST: + case StyleFilter::Tag::Contrast: result = SetAttributesForContrast(descr); break; - case NS_STYLE_FILTER_DROP_SHADOW: + case StyleFilter::Tag::DropShadow: result = SetAttributesForDropShadow(descr); break; - case NS_STYLE_FILTER_GRAYSCALE: + case StyleFilter::Tag::Grayscale: result = SetAttributesForGrayscale(descr); break; - case NS_STYLE_FILTER_HUE_ROTATE: + case StyleFilter::Tag::HueRotate: result = SetAttributesForHueRotate(descr); break; - case NS_STYLE_FILTER_INVERT: + case StyleFilter::Tag::Invert: result = SetAttributesForInvert(descr); break; - case NS_STYLE_FILTER_OPACITY: + case StyleFilter::Tag::Opacity: result = SetAttributesForOpacity(descr); break; - case NS_STYLE_FILTER_SATURATE: + case StyleFilter::Tag::Saturate: result = SetAttributesForSaturate(descr); break; - case NS_STYLE_FILTER_SEPIA: + case StyleFilter::Tag::Sepia: result = SetAttributesForSepia(descr); break; default: @@ -109,14 +109,9 @@ FilterPrimitiveDescription nsCSSFilterInstance::CreatePrimitiveDescription( nsresult nsCSSFilterInstance::SetAttributesForBlur( FilterPrimitiveDescription& aDescr) { - const nsStyleCoord& radiusInFrameSpace = mFilter.GetFilterParameter(); - if (radiusInFrameSpace.GetUnit() != eStyleUnit_Coord) { - MOZ_ASSERT_UNREACHABLE("unexpected unit"); - return NS_ERROR_FAILURE; - } - + const Length& radiusInFrameSpace = mFilter.AsBlur(); Size radiusInFilterSpace = - BlurRadiusToFilterSpace(radiusInFrameSpace.GetCoordValue()); + BlurRadiusToFilterSpace(radiusInFrameSpace.ToAppUnits()); GaussianBlurAttributes atts; atts.mStdDeviation = radiusInFilterSpace; aDescr.Attributes() = AsVariant(atts); @@ -125,8 +120,7 @@ nsresult nsCSSFilterInstance::SetAttributesForBlur( nsresult nsCSSFilterInstance::SetAttributesForBrightness( FilterPrimitiveDescription& aDescr) { - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = styleValue.GetFactorOrPercentValue(); + float value = mFilter.AsBrightness(); float intercept = 0.0f; ComponentTransferAttributes atts; @@ -147,8 +141,7 @@ nsresult nsCSSFilterInstance::SetAttributesForBrightness( nsresult nsCSSFilterInstance::SetAttributesForContrast( FilterPrimitiveDescription& aDescr) { - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = styleValue.GetFactorOrPercentValue(); + float value = mFilter.AsContrast(); float intercept = -(0.5 * value) + 0.5; ComponentTransferAttributes atts; @@ -169,7 +162,7 @@ nsresult nsCSSFilterInstance::SetAttributesForContrast( nsresult nsCSSFilterInstance::SetAttributesForDropShadow( FilterPrimitiveDescription& aDescr) { - const auto& shadow = mFilter.GetDropShadow(); + const auto& shadow = mFilter.AsDropShadow(); DropShadowAttributes atts; @@ -197,8 +190,7 @@ nsresult nsCSSFilterInstance::SetAttributesForGrayscale( atts.mType = (uint32_t)SVG_FECOLORMATRIX_TYPE_SATURATE; // Set color matrix values. - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = 1 - ClampFactor(styleValue.GetFactorOrPercentValue()); + float value = 1 - ClampFactor(mFilter.AsGrayscale()); atts.mValues.AppendElements(&value, 1); aDescr.Attributes() = AsVariant(std::move(atts)); @@ -212,8 +204,7 @@ nsresult nsCSSFilterInstance::SetAttributesForHueRotate( atts.mType = (uint32_t)SVG_FECOLORMATRIX_TYPE_HUE_ROTATE; // Set color matrix values. - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = styleValue.GetAngleValueInDegrees(); + float value = mFilter.AsHueRotate().ToDegrees(); atts.mValues.AppendElements(&value, 1); aDescr.Attributes() = AsVariant(std::move(atts)); @@ -223,8 +214,7 @@ nsresult nsCSSFilterInstance::SetAttributesForHueRotate( nsresult nsCSSFilterInstance::SetAttributesForInvert( FilterPrimitiveDescription& aDescr) { ComponentTransferAttributes atts; - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = ClampFactor(styleValue.GetFactorOrPercentValue()); + float value = ClampFactor(mFilter.AsInvert()); // Set transfer functions for RGB. float invertTableValues[2]; @@ -246,8 +236,7 @@ nsresult nsCSSFilterInstance::SetAttributesForInvert( nsresult nsCSSFilterInstance::SetAttributesForOpacity( FilterPrimitiveDescription& aDescr) { OpacityAttributes atts; - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = ClampFactor(styleValue.GetFactorOrPercentValue()); + float value = ClampFactor(mFilter.AsOpacity()); atts.mOpacity = value; aDescr.Attributes() = AsVariant(std::move(atts)); @@ -261,8 +250,7 @@ nsresult nsCSSFilterInstance::SetAttributesForSaturate( atts.mType = (uint32_t)SVG_FECOLORMATRIX_TYPE_SATURATE; // Set color matrix values. - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = styleValue.GetFactorOrPercentValue(); + float value = mFilter.AsSaturate(); atts.mValues.AppendElements(&value, 1); aDescr.Attributes() = AsVariant(std::move(atts)); @@ -276,8 +264,7 @@ nsresult nsCSSFilterInstance::SetAttributesForSepia( atts.mType = (uint32_t)SVG_FECOLORMATRIX_TYPE_SEPIA; // Set color matrix values. - const nsStyleCoord& styleValue = mFilter.GetFilterParameter(); - float value = ClampFactor(styleValue.GetFactorOrPercentValue()); + float value = ClampFactor(mFilter.AsSepia()); atts.mValues.AppendElements(&value, 1); aDescr.Attributes() = AsVariant(std::move(atts)); diff --git a/layout/svg/nsCSSFilterInstance.h b/layout/svg/nsCSSFilterInstance.h index 6610eddc99fb..5db26f62d7d1 100644 --- a/layout/svg/nsCSSFilterInstance.h +++ b/layout/svg/nsCSSFilterInstance.h @@ -13,9 +13,7 @@ #include "mozilla/gfx/Point.h" #include "mozilla/gfx/Types.h" #include "nsColor.h" -#include "nsTArrayForwardDeclare.h" - -struct nsStyleFilter; +#include "mozilla/ServoStyleConsts.h" /** * This class helps nsFilterInstance build its filter graph. It turns a CSS @@ -23,6 +21,7 @@ struct nsStyleFilter; * FilterPrimitiveDescription connected to the filter graph. */ class nsCSSFilterInstance { + using StyleFilter = mozilla::StyleFilter; typedef mozilla::gfx::Color Color; typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription; typedef mozilla::gfx::IntPoint IntPoint; @@ -41,7 +40,7 @@ class nsCSSFilterInstance { * the filtered element's frame space in CSS pixels to filter space. */ nsCSSFilterInstance( - const nsStyleFilter& aFilter, nscolor aShadowFallbackColor, + const StyleFilter& aFilter, nscolor aShadowFallbackColor, const nsIntRect& aTargetBoundsInFilterSpace, const gfxMatrix& aFrameSpaceInCSSPxToFilterSpaceTransform); @@ -121,7 +120,7 @@ class nsCSSFilterInstance { /** * The CSS filter originally from the style system. */ - const nsStyleFilter& mFilter; + const StyleFilter& mFilter; /** * The color that should be used for drop-shadow() filters that don't diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 57401319a4db..3d895bb2ed73 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -35,7 +35,7 @@ using namespace mozilla::gfx; using namespace mozilla::image; FilterDescription nsFilterInstance::GetFilterDescription( - nsIContent* aFilteredElement, const nsTArray& aFilterChain, + nsIContent* aFilteredElement, Span aFilterChain, bool aFilterInputIsTainted, const UserSpaceMetrics& aMetrics, const gfxRect& aBBox, nsTArray>& aOutAdditionalImages) { @@ -61,7 +61,7 @@ void nsFilterInstance::PaintFilteredFrame( nsIFrame* aFilteredFrame, gfxContext* aCtx, nsSVGFilterPaintCallback* aPaintCallback, const nsRegion* aDirtyArea, imgDrawingParams& aImgParams, float aOpacity) { - auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; + auto filterChain = aFilteredFrame->StyleEffects()->mFilters.AsSpan(); UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); @@ -121,7 +121,7 @@ bool nsFilterInstance::BuildWebRenderFilters(nsIFrame* aFilteredFrame, aWrFilters.filter_datas.Clear(); aWrFilters.values.Clear(); - auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; + auto filterChain = aFilteredFrame->StyleEffects()->mFilters.AsSpan(); UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); @@ -375,7 +375,7 @@ nsRegion nsFilterInstance::GetPostFilterDirtyArea( } gfxMatrix tm = nsSVGUtils::GetCanvasTM(aFilteredFrame); - auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; + auto filterChain = aFilteredFrame->StyleEffects()->mFilters.AsSpan(); UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); // Hardcode InputIsTainted to true because we don't want JS to be able to @@ -396,7 +396,7 @@ nsRegion nsFilterInstance::GetPostFilterDirtyArea( nsRegion nsFilterInstance::GetPreFilterNeededArea( nsIFrame* aFilteredFrame, const nsRegion& aPostFilterDirtyRegion) { gfxMatrix tm = nsSVGUtils::GetCanvasTM(aFilteredFrame); - auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; + auto filterChain = aFilteredFrame->StyleEffects()->mFilters.AsSpan(); UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); // Hardcode InputIsTainted to true because we don't want JS to be able to @@ -428,7 +428,7 @@ nsRect nsFilterInstance::GetPostFilterBounds(nsIFrame* aFilteredFrame, } gfxMatrix tm = nsSVGUtils::GetCanvasTM(aFilteredFrame); - auto& filterChain = aFilteredFrame->StyleEffects()->mFilters; + auto filterChain = aFilteredFrame->StyleEffects()->mFilters.AsSpan(); UniquePtr metrics = UserSpaceMetricsForFrame(aFilteredFrame); // Hardcode InputIsTainted to true because we don't want JS to be able to @@ -446,10 +446,9 @@ nsRect nsFilterInstance::GetPostFilterBounds(nsIFrame* aFilteredFrame, nsFilterInstance::nsFilterInstance( nsIFrame* aTargetFrame, nsIContent* aTargetContent, - const UserSpaceMetrics& aMetrics, - const nsTArray& aFilterChain, bool aFilterInputIsTainted, - nsSVGFilterPaintCallback* aPaintCallback, const gfxMatrix& aPaintTransform, - const nsRegion* aPostFilterDirtyRegion, + const UserSpaceMetrics& aMetrics, Span aFilterChain, + bool aFilterInputIsTainted, nsSVGFilterPaintCallback* aPaintCallback, + const gfxMatrix& aPaintTransform, const nsRegion* aPostFilterDirtyRegion, const nsRegion* aPreFilterDirtyRegion, const nsRect* aPreFilterVisualOverflowRectOverride, const gfxRect* aOverrideBBox) @@ -555,9 +554,9 @@ gfxRect nsFilterInstance::FilterSpaceToUserSpace( return userSpaceRect; } -nsresult nsFilterInstance::BuildPrimitives( - const nsTArray& aFilterChain, nsIFrame* aTargetFrame, - bool aFilterInputIsTainted) { +nsresult nsFilterInstance::BuildPrimitives(Span aFilterChain, + nsIFrame* aTargetFrame, + bool aFilterInputIsTainted) { nsTArray primitiveDescriptions; for (uint32_t i = 0; i < aFilterChain.Length(); i++) { @@ -577,13 +576,13 @@ nsresult nsFilterInstance::BuildPrimitives( } nsresult nsFilterInstance::BuildPrimitivesForFilter( - const nsStyleFilter& aFilter, nsIFrame* aTargetFrame, bool aInputIsTainted, + const StyleFilter& aFilter, nsIFrame* aTargetFrame, bool aInputIsTainted, nsTArray& aPrimitiveDescriptions) { NS_ASSERTION(mUserSpaceToFilterSpaceScale.width > 0.0f && mFilterSpaceToUserSpaceScale.height > 0.0f, "scale factors between spaces should be positive values"); - if (aFilter.GetType() == NS_STYLE_FILTER_URL) { + if (aFilter.IsUrl()) { // Build primitives for an SVG filter. nsSVGFilterInstance svgFilterInstance(aFilter, aTargetFrame, mTargetContent, mMetrics, mTargetBBox, diff --git a/layout/svg/nsFilterInstance.h b/layout/svg/nsFilterInstance.h index 5cfa3a4b8e46..4a717212ef2a 100644 --- a/layout/svg/nsFilterInstance.h +++ b/layout/svg/nsFilterInstance.h @@ -48,6 +48,10 @@ class UserSpaceMetrics; * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion */ class nsFilterInstance { + template + using Span = mozilla::Span; + using StyleFilter = mozilla::StyleFilter; + typedef mozilla::gfx::IntRect IntRect; typedef mozilla::gfx::SourceSurface SourceSurface; typedef mozilla::gfx::DrawTarget DrawTarget; @@ -71,7 +75,7 @@ class nsFilterInstance { * @return A FilterDescription describing the filter. */ static FilterDescription GetFilterDescription( - nsIContent* aFilteredElement, const nsTArray& aFilterChain, + nsIContent* aFilteredElement, Span aFilterChain, bool aFilterInputIsTainted, const UserSpaceMetrics& aMetrics, const gfxRect& aBBox, nsTArray>& aOutAdditionalImages); @@ -153,7 +157,7 @@ class nsFilterInstance { */ nsFilterInstance(nsIFrame* aTargetFrame, nsIContent* aTargetContent, const UserSpaceMetrics& aMetrics, - const nsTArray& aFilterChain, + Span aFilterChain, bool aFilterInputIsTainted, nsSVGFilterPaintCallback* aPaintCallback, const gfxMatrix& aPaintTransform, @@ -251,7 +255,7 @@ class nsFilterInstance { * mPrimitiveDescriptions and mInputImages. aFilterInputIsTainted describes * whether the SourceGraphic is tainted. */ - nsresult BuildPrimitives(const nsTArray& aFilterChain, + nsresult BuildPrimitives(Span aFilterChain, nsIFrame* aTargetFrame, bool aFilterInputIsTainted); /** @@ -261,8 +265,7 @@ class nsFilterInstance { * tainted. */ nsresult BuildPrimitivesForFilter( - const nsStyleFilter& aFilter, nsIFrame* aTargetFrame, - bool aInputIsTainted, + const StyleFilter& aFilter, nsIFrame* aTargetFrame, bool aInputIsTainted, nsTArray& aPrimitiveDescriptions); /** diff --git a/layout/svg/nsSVGFilterInstance.cpp b/layout/svg/nsSVGFilterInstance.cpp index 1aa0c64edf46..6fd3acda3aa0 100644 --- a/layout/svg/nsSVGFilterInstance.cpp +++ b/layout/svg/nsSVGFilterInstance.cpp @@ -29,7 +29,7 @@ using namespace mozilla::dom::SVGUnitTypes_Binding; using namespace mozilla::gfx; nsSVGFilterInstance::nsSVGFilterInstance( - const nsStyleFilter& aFilter, nsIFrame* aTargetFrame, + const StyleFilter& aFilter, nsIFrame* aTargetFrame, nsIContent* aTargetContent, const UserSpaceMetrics& aMetrics, const gfxRect& aTargetBBox, const gfxSize& aUserSpaceToFilterSpaceScale) : mFilter(aFilter), @@ -109,7 +109,7 @@ bool nsSVGFilterInstance::ComputeBounds() { } nsSVGFilterFrame* nsSVGFilterInstance::GetFilterFrame(nsIFrame* aTargetFrame) { - if (mFilter.GetType() != NS_STYLE_FILTER_URL) { + if (!mFilter.IsUrl()) { // The filter is not an SVG reference filter. return nullptr; } @@ -134,12 +134,12 @@ nsSVGFilterFrame* nsSVGFilterInstance::GetFilterFrame(nsIFrame* aTargetFrame) { url = urlExtraReferrer->GetURI(); } else { - url = mFilter.GetURL().ResolveLocalRef(mTargetContent); + url = mFilter.AsUrl().ResolveLocalRef(mTargetContent); } if (!url) { MOZ_ASSERT_UNREACHABLE( - "an nsStyleFilter of type URL should have a non-null URL"); + "an StyleFilter of type URL should have a non-null URL"); return nullptr; } @@ -147,8 +147,8 @@ nsSVGFilterFrame* nsSVGFilterInstance::GetFilterFrame(nsIFrame* aTargetFrame) { IDTracker idTracker; bool watch = false; idTracker.ResetToURIFragmentID( - mTargetContent, url, mFilter.GetURL().ExtraData().GetReferrer(), - mFilter.GetURL().ExtraData().GetReferrerPolicy(), watch); + mTargetContent, url, mFilter.AsUrl().ExtraData().GetReferrer(), + mFilter.AsUrl().ExtraData().GetReferrerPolicy(), watch); Element* element = idTracker.get(); if (!element) { // The URL points to no element. diff --git a/layout/svg/nsSVGFilterInstance.h b/layout/svg/nsSVGFilterInstance.h index 72f4c34fb39d..fd04234f5660 100644 --- a/layout/svg/nsSVGFilterInstance.h +++ b/layout/svg/nsSVGFilterInstance.h @@ -12,10 +12,9 @@ #include "SVGAnimatedNumber.h" #include "SVGAnimatedNumberPair.h" #include "SVGFilters.h" -#include "nsTArray.h" +#include "mozilla/ServoStyleConsts.h" class nsSVGFilterFrame; -struct nsStyleFilter; namespace mozilla { namespace dom { @@ -65,6 +64,7 @@ class SVGFilterElement; * "filter space point" = (20, 20) */ class nsSVGFilterInstance { + using StyleFilter = mozilla::StyleFilter; typedef mozilla::SVGAnimatedNumber SVGAnimatedNumber; typedef mozilla::SVGAnimatedNumberPair SVGAnimatedNumberPair; typedef mozilla::gfx::Point3D Point3D; @@ -83,7 +83,7 @@ class nsSVGFilterInstance { * @param aTargetBBox The SVG bbox to use for the target frame, computed by * the caller. The caller may decide to override the actual SVG bbox. */ - nsSVGFilterInstance(const nsStyleFilter& aFilter, nsIFrame* aTargetFrame, + nsSVGFilterInstance(const StyleFilter& aFilter, nsIFrame* aTargetFrame, nsIContent* aTargetContent, const UserSpaceMetrics& aMetrics, const gfxRect& aTargetBBox, @@ -202,7 +202,7 @@ class nsSVGFilterInstance { /** * The SVG reference filter originally from the style system. */ - const nsStyleFilter& mFilter; + const StyleFilter& mFilter; /** * The filtered element. diff --git a/servo/components/style/gecko/url.rs b/servo/components/style/gecko/url.rs index 8435895b8959..4f1efdf052cc 100644 --- a/servo/components/style/gecko/url.rs +++ b/servo/components/style/gecko/url.rs @@ -256,7 +256,6 @@ impl ToComputedValue for SpecifiedUrl { /// A specified image `url()` value. #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] -#[repr(C)] pub struct SpecifiedImageUrl(pub SpecifiedUrl); impl SpecifiedImageUrl { @@ -340,6 +339,7 @@ impl ToCss for ComputedUrl { /// The computed value of a CSS image `url()`. #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] +#[repr(transparent)] pub struct ComputedImageUrl(pub ComputedUrl); impl ComputedImageUrl { diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index 45e3124c8582..e5595673cb71 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -33,13 +33,11 @@ use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom; use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone; use crate::gecko_bindings::bindings::Gecko_SetListStyleImageImageValue; use crate::gecko_bindings::bindings::Gecko_SetNullImageValue; -use crate::gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsCSSPropertyID; use crate::gecko_bindings::structs::mozilla::PseudoStyleType; -use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut}; +use crate::gecko_bindings::sugar::ns_style_coord::CoordDataMut; use crate::gecko_bindings::sugar::refptr::RefPtr; -use crate::gecko::values::GeckoStyleCoordConvertible; use crate::gecko::values::round_border_to_device_pixels; use crate::logical_geometry::WritingMode; use crate::media_queries::Device; @@ -52,11 +50,10 @@ use std::marker::PhantomData; use std::mem::{forget, uninitialized, zeroed, ManuallyDrop}; use std::{cmp, ops, ptr}; use crate::values::{self, CustomIdent, Either, KeyframesName, None_}; -use crate::values::computed::{NonNegativeLength, Percentage, TransitionProperty}; +use crate::values::computed::{Percentage, TransitionProperty}; use crate::values::computed::url::ComputedImageUrl; use crate::values::computed::BorderStyle; use crate::values::computed::font::FontSize; -use crate::values::computed::effects::Filter; use crate::values::generics::column::ColumnCount; use crate::values::generics::transform::TransformStyle; use crate::values::generics::url::UrlOrNone; @@ -2162,6 +2159,7 @@ fn static_assert() { gecko_inexhaustive=True, ) %> ${impl_keyword('clear', 'mBreakType', clear_keyword)} + ${impl_transition_time_value('delay', 'Delay')} ${impl_transition_time_value('duration', 'Duration')} ${impl_transition_timing_function()} @@ -2926,8 +2924,7 @@ fn static_assert() { ${impl_simple_copy('_x_span', 'mSpan')} -<%self:impl_trait style_struct_name="Effects" - skip_longhands="clip filter"> +<%self:impl_trait style_struct_name="Effects" skip_longhands="clip"> pub fn set_clip(&mut self, v: longhands::clip::computed_value::T) { use crate::gecko_bindings::structs::NS_STYLE_CLIP_AUTO; use crate::gecko_bindings::structs::NS_STYLE_CLIP_RECT; @@ -3035,136 +3032,6 @@ fn static_assert() { Either::First(ClipRect { top, right, bottom, left }) } - - <% - # This array is several filter function which has percentage or - # number value for function of clone / set. - # The setting / cloning process of other function(e.g. Blur / HueRotate) is - # different from these function. So this array don't include such function. - FILTER_FUNCTIONS = [ 'Brightness', 'Contrast', 'Grayscale', 'Invert', - 'Opacity', 'Saturate', 'Sepia' ] - %> - - pub fn set_filter(&mut self, v: I) - where - I: IntoIterator, - I::IntoIter: ExactSizeIterator, - { - use crate::values::generics::effects::Filter::*; - use crate::gecko_bindings::structs::nsStyleFilter; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_CONTRAST; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_GRAYSCALE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_INVERT; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_OPACITY; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_SATURATE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_SEPIA; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_HUE_ROTATE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_DROP_SHADOW; - - fn fill_filter(m_type: u32, value: CoordDataValue, gecko_filter: &mut nsStyleFilter){ - gecko_filter.mType = m_type; - gecko_filter.mFilterParameter.set_value(value); - } - - let v = v.into_iter(); - unsafe { - Gecko_ResetFilters(&mut *self.gecko, v.len()); - } - debug_assert_eq!(v.len(), self.gecko.mFilters.len()); - - for (servo, gecko_filter) in v.zip(self.gecko.mFilters.iter_mut()) { - match servo { - % for func in FILTER_FUNCTIONS: - ${func}(factor) => fill_filter(NS_STYLE_FILTER_${func.upper()}, - CoordDataValue::Factor(factor.0), - gecko_filter), - % endfor - Blur(length) => fill_filter(NS_STYLE_FILTER_BLUR, - CoordDataValue::Coord(length.0.to_i32_au()), - gecko_filter), - - HueRotate(angle) => fill_filter(NS_STYLE_FILTER_HUE_ROTATE, - CoordDataValue::from(angle), - gecko_filter), - - DropShadow(shadow) => { - gecko_filter.mType = NS_STYLE_FILTER_DROP_SHADOW; - unsafe { - let ref mut union = gecko_filter.__bindgen_anon_1; - ptr::write(union.mDropShadow.as_mut(), shadow); - } - }, - Url(ref url) => { - unsafe { - bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url); - } - }, - } - } - } - - pub fn copy_filter_from(&mut self, other: &Self) { - unsafe { - Gecko_CopyFiltersFrom(&other.gecko as *const _ as *mut _, &mut *self.gecko); - } - } - - pub fn reset_filter(&mut self, other: &Self) { - self.copy_filter_from(other) - } - - pub fn clone_filter(&self) -> longhands::filter::computed_value::T { - use crate::values::generics::effects::Filter; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_BLUR; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_BRIGHTNESS; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_CONTRAST; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_GRAYSCALE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_INVERT; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_OPACITY; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_SATURATE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_SEPIA; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_HUE_ROTATE; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_DROP_SHADOW; - use crate::gecko_bindings::structs::NS_STYLE_FILTER_URL; - - longhands::filter::computed_value::List(self.gecko.mFilters.iter().map(|filter| { - match filter.mType { - % for func in FILTER_FUNCTIONS: - NS_STYLE_FILTER_${func.upper()} => { - Filter::${func}( - GeckoStyleCoordConvertible::from_gecko_style_coord( - &filter.mFilterParameter - ).unwrap() - ) - }, - % endfor - NS_STYLE_FILTER_BLUR => { - Filter::Blur(NonNegativeLength::from_gecko_style_coord( - &filter.mFilterParameter - ).unwrap()) - }, - NS_STYLE_FILTER_HUE_ROTATE => { - Filter::HueRotate(GeckoStyleCoordConvertible::from_gecko_style_coord( - &filter.mFilterParameter, - ).unwrap()) - }, - NS_STYLE_FILTER_DROP_SHADOW => { - Filter::DropShadow(unsafe { - (*filter.__bindgen_anon_1.mDropShadow.as_ref()).clone() - }) - }, - NS_STYLE_FILTER_URL => { - Filter::Url(unsafe { - filter.__bindgen_anon_1.mURL.as_ref().clone() - }) - } - _ => unreachable!("Unknown filter function?"), - } - }).collect()) - } - <%self:impl_trait style_struct_name="InheritedBox"> diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index d3b3ecd11e40..48f499c7ec3a 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -22,7 +22,7 @@ use std::mem::{self, ManuallyDrop}; use crate::hash::FxHashMap; use super::ComputedValues; use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; -use crate::values::animated::effects::Filter as AnimatedFilter; +use crate::values::animated::effects::AnimatedFilter; #[cfg(feature = "gecko")] use crate::values::computed::TransitionProperty; use crate::values::computed::{ClipRect, Context}; use crate::values::computed::ToComputedValue; diff --git a/servo/components/style/properties/longhands/effects.mako.rs b/servo/components/style/properties/longhands/effects.mako.rs index 9bb8adda32eb..c50a0d18ca63 100644 --- a/servo/components/style/properties/longhands/effects.mako.rs +++ b/servo/components/style/properties/longhands/effects.mako.rs @@ -47,6 +47,8 @@ ${helpers.predefined_type( "Filter", None, vector=True, + simple_vector_bindings=True, + gecko_ffi_name="mFilters", separator="Space", animation_value_type="AnimatedFilterList", vector_animation_type="with_zero", diff --git a/servo/components/style/values/animated/effects.rs b/servo/components/style/values/animated/effects.rs index 4c559cd4c30d..49e751fec555 100644 --- a/servo/components/style/values/animated/effects.rs +++ b/servo/components/style/values/animated/effects.rs @@ -19,8 +19,8 @@ pub type AnimatedSimpleShadow = GenericSimpleShadow; /// An animated value for a single `filter`. #[cfg(feature = "gecko")] -pub type Filter = GenericFilter; +pub type AnimatedFilter = GenericFilter; /// An animated value for a single `filter`. #[cfg(not(feature = "gecko"))] -pub type Filter = GenericFilter; +pub type AnimatedFilter = GenericFilter; diff --git a/servo/components/style/values/computed/effects.rs b/servo/components/style/values/computed/effects.rs index d103f407a75c..24ec689e49c2 100644 --- a/servo/components/style/values/computed/effects.rs +++ b/servo/components/style/values/computed/effects.rs @@ -24,7 +24,7 @@ pub type Filter = GenericFilter; /// A computed value for a single `filter`. -#[cfg(not(feature = "gecko"))] +#[cfg(feature = "servo")] pub type Filter = GenericFilter; diff --git a/servo/components/style/values/generics/effects.rs b/servo/components/style/values/generics/effects.rs index a27adc49e524..beca716e9970 100644 --- a/servo/components/style/values/generics/effects.rs +++ b/servo/components/style/values/generics/effects.rs @@ -34,8 +34,10 @@ pub struct GenericBoxShadow { pub use self::GenericBoxShadow as BoxShadow; /// A generic value for a single `filter`. +/// +/// cbindgen:derive-tagged-enum-copy-constructor=true #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] -#[animation(no_bound(Url))] +#[animation(no_bound(U))] #[derive( Clone, ComputeSquaredDistance, @@ -49,7 +51,8 @@ pub use self::GenericBoxShadow as BoxShadow; ToResolvedValue, ToShmem, )] -pub enum Filter { +#[repr(C, u8)] +pub enum GenericFilter { /// `blur()` #[css(function)] Blur(Length), @@ -79,12 +82,14 @@ pub enum Filter { Sepia(Factor), /// `drop-shadow(...)` #[css(function)] - DropShadow(DropShadow), + DropShadow(Shadow), /// `` #[animation(error)] - Url(Url), + Url(U), } +pub use self::GenericFilter as Filter; + /// A generic value for the `drop-shadow()` filter and the `text-shadow` property. /// /// Contrary to the canonical order from the spec, the color is serialised diff --git a/servo/components/style/values/specified/effects.rs b/servo/components/style/values/specified/effects.rs index 3ffad2fa89cd..24af52d15564 100644 --- a/servo/components/style/values/specified/effects.rs +++ b/servo/components/style/values/specified/effects.rs @@ -18,7 +18,7 @@ use crate::values::specified::length::{Length, NonNegativeLength}; #[cfg(feature = "gecko")] use crate::values::specified::url::SpecifiedUrl; use crate::values::specified::{Angle, Number, NumberOrPercentage}; -#[cfg(not(feature = "gecko"))] +#[cfg(feature = "servo")] use crate::values::Impossible; use crate::Zero; use cssparser::{self, BasicParseErrorKind, Parser, Token}; @@ -30,11 +30,13 @@ pub type BoxShadow = /// A specified value for a single `filter`. #[cfg(feature = "gecko")] -pub type Filter = GenericFilter; +pub type SpecifiedFilter = GenericFilter; /// A specified value for a single `filter`. -#[cfg(not(feature = "gecko"))] -pub type Filter = GenericFilter; +#[cfg(feature = "servo")] +pub type SpecifiedFilter = GenericFilter; + +pub use self::SpecifiedFilter as Filter; /// A value for the `` parts in `Filter`. #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)] diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml index 9e99fb7f3851..3ed6f2d4d3b5 100644 --- a/servo/ports/geckolib/cbindgen.toml +++ b/servo/ports/geckolib/cbindgen.toml @@ -35,6 +35,11 @@ include = ["style", "cssparser", "style_traits", "servo_arc"] derive_eq = true derive_neq = true +[defines] +# This will actually never be defined, but is handy to avoid cbindgen +# generating Servo-only types. +"feature = servo" = "CBINDGEN_IS_SERVO" + [macro_expansion] bitflags = true @@ -143,6 +148,7 @@ include = [ "ComputedUrl", "ComputedImageUrl", "UrlOrNone", + "Filter", ] item_types = ["enums", "structs", "typedefs", "functions"] renaming_overrides_prefixing = true @@ -364,15 +370,16 @@ renaming_overrides_prefixing = true ptr((T*)alignof(T)), len(0) {} - // Should be easily implementable if wanted, but the default implementation would leak. - StyleOwnedSlice& operator=(const StyleOwnedSlice&) = delete; - StyleOwnedSlice& operator=(StyleOwnedSlice&&) = delete; + inline void Clear(); + inline void CopyFrom(const StyleOwnedSlice&); + inline void SwapElements(StyleOwnedSlice&); + + StyleOwnedSlice& operator=(const StyleOwnedSlice&); + StyleOwnedSlice& operator=(StyleOwnedSlice&&); inline StyleOwnedSlice(const StyleOwnedSlice&); inline StyleOwnedSlice(StyleOwnedSlice&&); - inline void Clear(); - inline ~StyleOwnedSlice(); Span AsSpan() const { @@ -457,6 +464,9 @@ renaming_overrides_prefixing = true inline bool IsStatic() const; inline nsAtom* AsAtom() const; + // Could be implemented if wanted. + StyleAtom& operator=(const StyleAtom&) = delete; + inline StyleAtom(const StyleAtom& aOther); inline ~StyleAtom(); """